AngularJS - 如何将 html 属性变量值传递给指令?
AngularJS - How to pass html attribute variable value to directive?
...
...
更新
HTML
<my-directive ng-repeat="item in items = ( data | filter: {isExists: true})">
something
</my-directive>
<my-second-directive counter="{{items.length}}"></my-second-directive>
JS
angular.module('directives')
.directive('myDirective', function () {
...
})
.directive('mySecondDirective', function () {
return {
restrict: 'EA',
transclude: false,
replace: true,
scope: {
counter: '@'
},
template: '',
link: function (scope, element, attrs) {
alert(scope.counter);
}
});
对不起,我没有很好地描述我的问题。我的第一个指令应该是 ngRepeated,带有过滤器。但是在我的第二个指令中,我想允许显示一个计数器,当前实例化了多少个第一个指令,因为用户将能够添加和删除实例。所以我想通过第二个指令获得 items.length 的值。但是第二个指令的 link() 方法在 ngRepeat 之前触发,所以计数器的值将是一个空字符串。
提前致谢
更新 2
.directive('cardGroupHeader', function($templateCache){
return {
restrict: 'EA',
transclude: true,
replace: true,
require: '^cardGroup',
scope: {
cbiscounter: '=?',
cbcounter: '=?',
cbisarrow: '@?'
},
template: $templateCache.get('card-group-header-tpl.html'),
link: function(scope, $element, $attrs, cardGroupController) {
scope.rowId = cardGroupController.getCurrentId();
console.log(scope.cbcounter);
scope.toggle = function () {
cardGroupController.toggle(scope.rowId)
}
angular.element(document).ready(function () {
console.log(scope.cbcounter);
});
scope.$watch('scope.cbcounter', function (n, o) {
if(n && n != o) {
console.log(n);
}
});
//scope.cbcounter++;
}
};
})
HTML
<card-group-header cbiscounter="true" cbarrow="true" cbcounter="data.length">Waiting for Approval</card-group-header>
<card-group-row cbCollapsed="false">
<card ng-repeat="approveItem in data = (approveItems | filter: {isApproved: false, isRejected: false})">
模板
$templateCache.put('card-group-header-tpl.html', '<div class="card-group-header" ng-click="toggle()"><span ng-transclude></span><span class="card-group-counter" ng-if="cbiscounter">{{cbcounter}}</span></div>');
当我把data.length
改成2
的时候,这个就转好了。如果我使用 data.length
,则 scope.cbcounter
始终未定义。如果是 2
我已经在 console.log(scope.cbcounter);
上找回了
counter: '@'
表示您正在接受一个字符串值。如果你想传递一个表达式,你可以使用:
<my-second-directive counter="{{ items.length }}"></my-second-directive>
或者:
.directive('mySecondDirective', function () {
return {
restrict: 'EA',
transclude: false,
replace: true,
scope: {
counter: '=' // Accept two ways binding
},
template: '',
link: function (scope, element, attrs) {
alert(scope.counter);
}
});
编辑:
我终于很明白这个问题了!这是因为 直到 link 阶段 之后才对属性进行插值。您有以下两个选择:
第一个选项是将 link 中的 every 包装在 $timeout
内,将其从事件循环中取出并在 DOM 完成操作后执行:
.directive('mySecondDirective', function ($timeout) {
return {
restrict: 'EA',
transclude: false,
replace: true,
scope: {
counter: '=' // Accept two ways binding
},
template: '',
link: function (scope, element, attrs) {
$timeout(function() {
alert(scope.counter);
});
}
});
其次,使用$observe
:
attrs.$observe('counter', function(value){
console.log(value);
});
或按照@jusopi的建议使用$watch
。
我想这就是你想要的。
Html
<div ng-app="testapp" ng-controller="testctrl">
<div ng-repeat="item in filtereditems">
{{item}}
</div>
<testdir counter="filtereditems.length" />
</div>
Javascript
angular.module('testapp', [])
.directive('testdir', function(){
return {
restrict: 'E',
scope:{
counter: '='
},
link: function(scope, element, attrs) {
alert(scope.counter);
}
}
})
.controller('testctrl', function($scope, $filter){
$scope.items = [
{name: 'A', isExists: true},
{name: 'B', isExists: false},
{name: 'C', isExists: true},
{name: 'D', isExists: false}
];
$scope.filtereditems = $filter('filter')($scope.items, {isExists: true});
})
除了@LVarayut 关于作用域绑定表达式的回答之外,警报是 undefined
的原因是因为链接不是 $digest 循环的一部分。因此绑定和数据尚未生效(不要引用我的话,这是我可以用语言表达我在下面的代码中显示的内容的最佳方式)。
相反,您需要使用观察器来触发警报
link: ($scope, elem, attrs)->
#undefined because linking isn't part of the $digest cycle
#alert $scope.count
$scope.$watch 'count', (n, o)->
if n and n isnt o
true
#alert n
... ...
更新
HTML
<my-directive ng-repeat="item in items = ( data | filter: {isExists: true})">
something
</my-directive>
<my-second-directive counter="{{items.length}}"></my-second-directive>
JS
angular.module('directives')
.directive('myDirective', function () {
...
})
.directive('mySecondDirective', function () {
return {
restrict: 'EA',
transclude: false,
replace: true,
scope: {
counter: '@'
},
template: '',
link: function (scope, element, attrs) {
alert(scope.counter);
}
});
对不起,我没有很好地描述我的问题。我的第一个指令应该是 ngRepeated,带有过滤器。但是在我的第二个指令中,我想允许显示一个计数器,当前实例化了多少个第一个指令,因为用户将能够添加和删除实例。所以我想通过第二个指令获得 items.length 的值。但是第二个指令的 link() 方法在 ngRepeat 之前触发,所以计数器的值将是一个空字符串。
提前致谢
更新 2
.directive('cardGroupHeader', function($templateCache){
return {
restrict: 'EA',
transclude: true,
replace: true,
require: '^cardGroup',
scope: {
cbiscounter: '=?',
cbcounter: '=?',
cbisarrow: '@?'
},
template: $templateCache.get('card-group-header-tpl.html'),
link: function(scope, $element, $attrs, cardGroupController) {
scope.rowId = cardGroupController.getCurrentId();
console.log(scope.cbcounter);
scope.toggle = function () {
cardGroupController.toggle(scope.rowId)
}
angular.element(document).ready(function () {
console.log(scope.cbcounter);
});
scope.$watch('scope.cbcounter', function (n, o) {
if(n && n != o) {
console.log(n);
}
});
//scope.cbcounter++;
}
};
})
HTML
<card-group-header cbiscounter="true" cbarrow="true" cbcounter="data.length">Waiting for Approval</card-group-header>
<card-group-row cbCollapsed="false">
<card ng-repeat="approveItem in data = (approveItems | filter: {isApproved: false, isRejected: false})">
模板
$templateCache.put('card-group-header-tpl.html', '<div class="card-group-header" ng-click="toggle()"><span ng-transclude></span><span class="card-group-counter" ng-if="cbiscounter">{{cbcounter}}</span></div>');
当我把data.length
改成2
的时候,这个就转好了。如果我使用 data.length
,则 scope.cbcounter
始终未定义。如果是 2
我已经在 console.log(scope.cbcounter);
counter: '@'
表示您正在接受一个字符串值。如果你想传递一个表达式,你可以使用:
<my-second-directive counter="{{ items.length }}"></my-second-directive>
或者:
.directive('mySecondDirective', function () {
return {
restrict: 'EA',
transclude: false,
replace: true,
scope: {
counter: '=' // Accept two ways binding
},
template: '',
link: function (scope, element, attrs) {
alert(scope.counter);
}
});
编辑: 我终于很明白这个问题了!这是因为 直到 link 阶段 之后才对属性进行插值。您有以下两个选择:
第一个选项是将 link 中的 every 包装在 $timeout
内,将其从事件循环中取出并在 DOM 完成操作后执行:
.directive('mySecondDirective', function ($timeout) {
return {
restrict: 'EA',
transclude: false,
replace: true,
scope: {
counter: '=' // Accept two ways binding
},
template: '',
link: function (scope, element, attrs) {
$timeout(function() {
alert(scope.counter);
});
}
});
其次,使用$observe
:
attrs.$observe('counter', function(value){
console.log(value);
});
或按照@jusopi的建议使用$watch
。
我想这就是你想要的。
Html
<div ng-app="testapp" ng-controller="testctrl">
<div ng-repeat="item in filtereditems">
{{item}}
</div>
<testdir counter="filtereditems.length" />
</div>
Javascript
angular.module('testapp', [])
.directive('testdir', function(){
return {
restrict: 'E',
scope:{
counter: '='
},
link: function(scope, element, attrs) {
alert(scope.counter);
}
}
})
.controller('testctrl', function($scope, $filter){
$scope.items = [
{name: 'A', isExists: true},
{name: 'B', isExists: false},
{name: 'C', isExists: true},
{name: 'D', isExists: false}
];
$scope.filtereditems = $filter('filter')($scope.items, {isExists: true});
})
除了@LVarayut 关于作用域绑定表达式的回答之外,警报是 undefined
的原因是因为链接不是 $digest 循环的一部分。因此绑定和数据尚未生效(不要引用我的话,这是我可以用语言表达我在下面的代码中显示的内容的最佳方式)。
相反,您需要使用观察器来触发警报
link: ($scope, elem, attrs)->
#undefined because linking isn't part of the $digest cycle
#alert $scope.count
$scope.$watch 'count', (n, o)->
if n and n isnt o
true
#alert n