符合John Papa的style guide我更新了我的指令以使用ControllerAs语法。但是,在执行此操作后,我的指令在对指令绑定的变量进行更改时不会更新。
即。当mainCtrl.rules更新时,ctrl.rules的值不会更新
要解决这个问题,我必须在链接函数中创建一个监视,当$ scope.rules更改时更新ctrl.rules变量。
为什么这是 - 指令和控制器不在同一范围内?
HTML
<div my-directive rules="mainCtrl.rules"></div>
JS - 主Ctrl
rulesService.get().then(mainCtrl.rules = response.rules;);
JS - 指令
(function () {
angular.module('myModule')
.directive('myDirective', myDirective);
myDirective.$inject = [];
function myDirective()
{
var directive = {
restrict: 'A',
scope: {
rules: '='
},
controller: 'myCtrl',
controllerAs: 'ctrl',
templateUrl: "/Template/myDirective",
transclude: true,
link: linkFunc
};
return directive;
};
angular.module('myModule')
.controller('myCtrl', myCtrl);
myCtrl.$inject = ['$scope'];
function myCtrl($scope)
{
var ctrl = this;
ctrl.rules = $scope.rules;
ctrl.showRules = false;
ctrl.toggleShowRules = toggleShowRules;
function toggleShowRules() {
ctrl.showRules = !ctrl.showRules;
};
};
function linkFunc($scope, $element, $attrs, ctrl)
{
//watch the rules collection on the directive and update controller if it changes
$scope.$watch("rules", function (newValue, oldValue) {
if(newValue != oldValue)
{
ctrl.rules = newValue;
}
});
};
})();
TEMPLATE
<div class="rules" ng-show="rules.length > 0">
<ul ng-show="ctrl.showRules">
<li ng-repeat="rule in ctrl.rules" class="rule-details">
<p>{{rule.title}}</p>
</li>
</ul>
</div>
答案 0 :(得分:0)
您的链接函数$scope
不是提供者,它是指令的隔离scope
,所以我认为你所拥有的是一个ctrl,其中this
不是指令,但它是构造函数。
我认为如果你做这样的事情,你会看到差异。
function myCtrl($scope, $attrs, $log) {
this.scope = $scope;
$log.debug(this);
// vs
$log.debug(this.scope);
答案 1 :(得分:0)
在ctrl.rules = $scope.rules;
中,有问题的代码是myCtrl
,这将指向现有的规则列表。然后,当rulesService.get().then(mainCtrl.rules = response.rules;);
出现时,它会将指令中的$scope.rules
设置为指向新数据,但ctrl.rules
仍然指向旧列表。有两种方法可以在不对代码进行重大更改的情况下解决此问题。
选项1 :您可以更新mainCtrl
,而不是替换mainCtrl.rules.length = 0;
angular.extend(mainCtrl.rules, response.rules);
中的引用:
ctrl.rules
该选项虽然有点昂贵,但因为存在循环涉及使用新值更新参考。
选项2 :您可以创建一个返回$scope.rules
而不是$scope.rules
您的函数,而不是将ctrl.rules = $scope.rules
设置为引用ctrl.getRules = function () { return $scope.rules; }
可以做到以下几点:
ng-repeat
然后在您的模板中将<li ng-repeat="rule in ctrl.getRules()" class="rule-details">
更改为
{{1}}
选项2有点容易理解,而选项1对于那些试图阅读代码的人更难理解。