Har*_*nis 14 angularjs angularjs-directive angularjs-scope
我想要实现的是为输入字段添加额外的接口,以便通过单击+和 - 按钮来增加和减少其中的数值.
(本质上它是输入[type = number]字段在chrome上的内容,但我希望这是跨浏览兼容的,并且还可以完全控制所有浏览器的演示文稿).
代码在视图中:
<input data-ng-model="session.amountChosen" type="text" min="1" class="form-control input-small" data-number-input>
Run Code Online (Sandbox Code Playgroud)
指令代码:
app.directive('numberInput', function() {
return {
require: 'ngModel',
scope: true,
link: function(scope, elm, attrs, ctrl) {
var currValue = parseInt(scope.$eval(attrs.ngModel)),
minValue = attrs.min || 0,
maxValue = attrs.max || Infinity,
newValue;
//puts a wrap around the input and adds + and - buttons
elm.wrap('<div class="number-input-wrap"></div>').parent().append('<div class="number-input-controls"><a href="#" class="btn btn-xs btn-pluimen">+</a><a href="#" class="btn btn-xs btn-pluimen">-</a></div>');
//finds the buttons ands binds a click event to them where the model increase/decrease should happen
elm.parent().find('a').bind('click',function(e){
if(this.text=='+' && currValue<maxValue) {
newValue = currValue+1;
} else if (this.text=='-' && currValue>minValue) {
newValue = currValue-1;
}
scope.$apply(function(){
scope.ngModel = newValue;
});
e.preventDefault();
});
}
};
Run Code Online (Sandbox Code Playgroud)
})
这可以通过范围.$ eval(attrs.ngModel)检索当前模型值,但无法设置新值.
后果编辑:这是现在可以使用的代码(如果您不想看到此问题的解决方案)
app.directive('numberInput', function() {
return {
require: 'ngModel',
scope: true,
link: function(scope, elm, attrs, ctrl) {
var minValue = attrs.min || 0,
maxValue = attrs.max || Infinity;
elm.wrap('<div class="number-input-wrap"></div>').parent().append('<div class="number-input-controls"><a href="#" class="btn btn-xs btn-pluimen">+</a><a href="#" class="btn btn-xs btn-pluimen">-</a></div>');
elm.parent().find('a').bind('click',function(e){
var currValue = parseInt(scope.$eval(attrs.ngModel)),
newValue = currValue;
if(this.text=='+' && currValue<maxValue) {
newValue = currValue+1;
} else if (this.text=='-' && currValue>minValue) {
newValue = currValue-1;
}
scope.$eval(attrs.ngModel + "=" + newValue);
scope.$apply();
e.preventDefault();
});
}
};
})
Run Code Online (Sandbox Code Playgroud)
Mar*_*cok 29
应使用ngModelController方法代替$ eval()来获取和设置ng-model属性的值.
在使用数值计算属性时不需要parseInt(),因为$ eval会将值转换为数字.$ eval应该用于设置变量minValue和maxValue.
指令不需要创建子范围.
因为ngModelController方法(特别是$ render())将自动更新视图,所以不需要$ apply().但是,正如@Harijs在下面的评论中指出的那样,如果应用的其他部分也需要更新,则需要$ apply().
app.directive('numberInput', function ($parse) {
return {
require: 'ngModel',
link: function (scope, elm, attrs, ctrl) {
var minValue = scope.$eval(attrs.min) || 0,
maxValue = scope.$eval(attrs.max) || Infinity;
elm.wrap('<div class="number-input-wrap"></div>').parent()
.append('<div class="number-input-controls"><a href="#" class="btn btn-xs btn-pluimen">+</a><a href="#" class="btn btn-xs btn-pluimen">-</a></div>');
elm.parent().find('a').bind('click', function (e) {
var currValue = ctrl.$modelValue,
newValue;
if (this.text === '+' && currValue < maxValue) {
newValue = currValue + 1;
} else if (this.text === '-' && currValue > minValue) {
newValue = currValue - 1;
}
ctrl.$setViewValue(newValue);
ctrl.$render();
e.preventDefault();
scope.$apply(); // needed if other parts of the app need to be updated
});
}
};
});
Run Code Online (Sandbox Code Playgroud)