AngularJS 一个简单的控件:评级
示例
让我们构建一个简单的控件,一个评级小部件,旨在用作:
<rating min="0" max="5" nullifier="true" ng-model="data.rating"></rating>
暂时没有精美的CSS;这将呈现为:
0 1 2 3 4 5 x
点击一个数字即可选择该等级;然后点击“x”,则将评分设置为null。
app.directive('rating', function() {
function RatingController() {
this._ngModel= null;
this.rating= null;
this.options= null;
this.min= typeofthis.min=== 'number' ?this.min: 1;
this.max= typeofthis.max=== 'number' ?this.max: 5;
}
RatingController.prototype.setNgModel = function(ngModel) {
this._ngModel= ngModel;
if( ngModel ) {
//要点1
ngModel.$render = this._render.bind(this);
}
};
RatingController.prototype._render = function() {
this.rating= this._ngModel.$viewValue != null ? this._ngModel.$viewValue : -Number.MAX_VALUE;
};
RatingController.prototype._calculateOptions = function() {
if(this.min== null ||this.max== null ) {
this.options= [];
}
else {
this.options= new Array(this.max -this.min+ 1);
for( var i=0; i < this.options.length; i++ ) {
this.options[i] =this.min+ i;
}
}
};
RatingController.prototype.setValue = function(val) {
this.rating= val;
//要点2
this._ngModel.$setViewValue(val);
};
//要点3
Object.defineProperty(RatingController.prototype, 'min', {
get: function() {
return this._min;
},
set: function(val) {
this._min= val;
this._calculateOptions();
}
});
Object.defineProperty(RatingController.prototype, 'max', {
get: function() {
return this._max;
},
set: function(val) {
this._max= val;
this._calculateOptions();
}
});
return {
restrict: 'E',
scope: {
//要点3
min: '<?',
max: '<?',
nullifier: '<?'
},
bindToController: true,
controllerAs: 'ctrl',
controller: RatingController,
require: ['rating', 'ngModel'],
link: function(scope, elem, attrs, ctrls) {
ctrls[0].setNgModel(ctrls[1]);
},
template:
'<span ng-repeat="o in ctrl.options" href="#" class="rating-option" ng-class="{\'rating-option-active\': o <= ctrl.rating}" ng-click="ctrl.setValue(o)">{{ o }}</span>' +
'<span ng-if="ctrl.nullifier" ng-click="ctrl.setValue(null)" class="rating-nullifier">✖</span>'
};
});关键点:
实施ngModel.$render以将模型的视图值传输到您的视图。
每当您认为视图值应更新时就致电。ngModel.$setViewValue()
当然可以对控制进行参数设置;使用'<'范围绑定作为参数(如果在Angular>=1.5中)以明确指示输入-一种单向绑定。如果必须在参数更改时采取措施,则可以使用JavaScript属性(请参阅参考资料)来保存一些手表。Object.defineProperty()
注1:为了不使实现复杂化,将额定值插入到数组-中ctrl.options。这是不需要的。一个更有效,但也更复杂,实现可以使用DOM操作时插入/删除收视率min/max变化。
注2:除'<'范围绑定外,此示例可在Angular<1.5中使用。如果您使用的是Angular>=1.5,则最好将其转换为组件并使用生命周期钩子来初始化和,而不是在控制器的构造函数中进行初始化。$onInit()minmax
还有一个必要的提琴:https://jsfiddle.net/h81mgxma/