如何在父作用域中访问AngularJS指令的invalid属性?
问题描述
我定义了一个AngularJS指令searchFilters,代码如下:
(function () { /** * Config */ var moduleName = 'eBayPartsFinder.directives.searchFilters'; /** * Module */ angular.module(moduleName, []).directive('searchFilters', searchFiltersDirective); function searchFiltersDirective($timeout) { return { restrict: 'E', scope: { model: '=', disabled: '=', onChange: '&' }, templateUrl: BASE_URL + '/lib/EbayPartsFinder/SearchFilters.html', link: function ($scope, element, attrs) { attrs.$set('invalid', true); } }; }})();
在父页面使用该指令时,尝试通过ng-disabled="searchFilters.invalid"控制按钮禁用状态,但无法访问到指令的invalid属性。父页面代码如下:
<search-filters id="BatchResultFilters" name="searchFilters" model="FiltersStaging.GlobalFilters" disabled="Searching"></search-filters> <button class="btn btn-primary btn-sm" ng-click="ApplyFilters()" ng-disabled="searchFilters.invalid" tabindex="15">Apply Filter</button>
请问该如何实现父作用域访问指令的invalid属性?
解决方案
方法一:双向绑定同步状态(推荐)
通过给指令添加双向绑定属性,让指令内部的invalid状态自动同步到父作用域:
- 修改指令的
scope配置,新增invalid双向绑定:
scope: { model: '=', disabled: '=', onChange: '&', invalid: '=' // 添加双向绑定 },
- 在指令的
link函数中,直接操作作用域上的invalid属性,替代原来的attrs.$set:
link: function ($scope, element, attrs) { $scope.invalid = true; // 初始化状态 // 后续需要更新状态时,直接修改$scope.invalid即可,会自动同步到父作用域 }
- 父页面中绑定指令的
invalid属性到父作用域变量,并用该变量控制按钮:
<search-filters id="BatchResultFilters" name="searchFilters" model="FiltersStaging.GlobalFilters" disabled="Searching" invalid="filterInvalid"></search-filters> <button class="btn btn-primary btn-sm" ng-click="ApplyFilters()" ng-disabled="filterInvalid" tabindex="15">Apply Filter</button>
注意:父作用域需要提前定义filterInvalid变量(可在控制器中初始化)。
方法二:通过回调传递状态
如果不想用双向绑定,可以利用指令已有的onChange回调来传递invalid状态:
- 在指令的
link函数中,触发回调把状态传递给父作用域:
link: function ($scope, element, attrs) { let invalid = true; attrs.$set('invalid', invalid); // 调用回调传递状态 $scope.onChange({invalid: invalid}); // 后续状态更新时,同样调用$scope.onChange({invalid: 新状态}) }
- 父页面中通过回调接收状态并赋值给父作用域变量:
<search-filters id="BatchResultFilters" name="searchFilters" model="FiltersStaging.GlobalFilters" disabled="Searching" onChange="filterInvalid = invalid"></search-filters> <button class="btn btn-primary btn-sm" ng-click="ApplyFilters()" ng-disabled="filterInvalid" tabindex="15">Apply Filter</button>
方法三:利用表单内置状态(如果指令内包含表单)
如果你的SearchFilters.html模板里有表单,可以直接复用表单的$invalid状态:
- 确保模板内的表单设置
name属性:
<!-- SearchFilters.html 模板内 --> <form name="filtersForm"> <!-- 各类表单控件 --> </form>
- 在指令的
link函数中,监听表单的$invalid变化并同步到父作用域:
link: function ($scope, element, attrs) { $scope.$watch('filtersForm.$invalid', function(newInvalidState) { // 用双向绑定同步:$scope.invalid = newInvalidState; // 或用回调传递:$scope.onChange({invalid: newInvalidState}); }); }
之后父作用域就能通过之前的方法获取到实时的表单无效状态。
内容的提问来源于stack exchange,提问作者Vadim Buryakovsky
相关产品推荐
相关产品推荐

