我正在尝试为计数器小部件实现自定义指令。
我已经能够实现它,但有很多事情我需要一些亮点。
scope:
(隔离范围)?startnumber
重置为“1”?scope
从哪里继承?是否继承自被调用的元素? HTML 代码段
<body>
<counter-widget startnumber=1 ></counter-widget>
<counter-widget startnumber=1 ></counter-widget>
<counter-widget startnumber=1 ></counter-widget>
</body>
JS 代码段
angular.module("myApp",[])
.directive("counterWidget",function(){
return{
restrict:"E",
scope:{
},
link:function(scope,elem,attr){
scope.f = attr.startnumber;
scope.add = function(){
scope.f = Number(scope.f) + 1;
}
scope.remove = function(){
scope.f =Number(scope.f) - 1;
}
scope.reset = function(){
scope.f = 1;
}
},
template:"<button ng-click='add()'>more</button>"+
"{{f}}"+
"<button ng-click='remove()'>less</button> "+
"<button ng-click='reset()'>reset</button><br><br>"
}
})
提前感谢您的帮助。
答案 0 :(得分:1)
首先,传入你的startnumber属性,这样我们就可以重置为那个数字而不必在数字中加硬编码。
如果您要使用多个计数器,则需要隔离范围。 但以下是如何实现全局重置:
app.directive("counterWidget",function(){
return{
restrict:"E",
scope:{
startnumber: '=',
resetter: '='
},
link:function(scope,elem,attr){
scope.f = attr.startnumber;
scope.add = function(){
scope.f++
}
scope.remove = function(){
scope.f--
}
scope.reset = function(){
scope.f = attr.startnumber
scope.$parent.triggerReset()
}
scope.$watch(function(attr) {
return attr.resetter
},
function(newVal) {
if (newVal === true) {
scope.f = attr.startnumber;
}
})
},
template:"<button ng-click='add()'>more</button>"+
"{{f}}"+
"<button ng-click='remove()'>less</button> "+
"<button ng-click='reset()'>reset</button><br><br>"
}
})
在控制器中,您只需添加一个小的重置功能,每个指令都在观察:
$scope.triggerReset = function () {
$scope.reset = true;
console.log('reset')
$timeout(function() {
$scope.reset = false;
},100)
}
我不会过度复杂递减和递增函数。 ++和 - 应该没问题。
我们通过添加属性并将其传递给指令来创建全局重置功能。然后,我们将该属性视为真正的价值。每当我们点击重置时,我们在$ parent范围内触发一个函数(triggerReset()函数)。该函数快速切换$ scope.reset值。任何在其重置器属性中具有该绑定的指令都将重置为startnumber属性中的任何内容。
另一个好处是重置只会影响你想要的计数器。您甚至可以创建多组计数器,这些计数器仅重置其自己的组中的计数器。您只需要为每个要为其自己重置的组添加触发器功能和变量。 这是演示:
<强> Plunker 强>
修改强>
所以问题出现在评论中 - $ watch功能可以错过&#39;切换? 我做了一些测试,到目前为止我得到的最佳答案是,如果我将它设置为1ms甚至完全删除时间参数,那么$ watch仍会触发。 我也在这里向社区提出了这个问题:Can $watch 'miss'?
答案 1 :(得分:0)
您可以在html中使用ng-repeat。您可以定义count = 3
<body>
<div ng-repeat="index in count">
<counter-widget startnumber=1 ></counter-widget></div>
</body>
也请点击链接。他们以更好的方式解释了范围继承
http://www.sitepoint.com/practical-guide-angularjs-directives-part-two/
父范围(范围:false) - 这是默认情况。如果您的指令不操作父作用域属性,则可能不需要新作用域。在这种情况下,使用父作用域是可以的。
子范围(范围:true) - 这为原型继承父范围的指令创建了一个新的子范围。如果在作用域上设置的属性和函数与其他指令和父作业无关,则应该创建一个新的子作用域。通过这种方式,您还可以获得父级定义的所有范围属性和函数。
隔离范围(范围:{}) - 这就像一个沙箱!如果要构建的指令是自包含且可重用的,则需要此选项。您的指令可能会创建许多用于内部使用的范围属性和函数,并且永远不会被外界看到。如果是这种情况,最好有一个孤立的范围。正如预期的那样,隔离范围不会继承父范围。
答案 2 :(得分:0)
这将是一种更好的方法。
<强> HTML 强>
<body>
<counter-widget counter="controllerScopeVariable" ></counter-widget>
</body>
<强> JS 强>
angular.module("myApp",[])
.directive("counterWidget",function(){
return{
restrict:"E",
scope:{
counter:'='
},
link:function(scope,elem,attr){
scope.counter = parseInt(scope.counter);
scope.add = function(){
scope.counter+=1;
}
scope.remove = function(){
scope.counter-=1;
}
scope.reset = function(){
scope.counter = 1;
}
},
template:"<button ng-click='add()'>more</button>"+
"{{f}}"+
"<button ng-click='remove()'>less</button> "+
"<button ng-click='reset()'>reset</button><br><br>"
}
});