Angular 指令 formatter/render 不更新
Angular Directive formatter/render does not update
我写了一个很简单的 directive 转分钟
进入范围滑块,并在其旁边显示 小时 和 分钟。
问题是移动范围滑块确实会更新范围,
所以 Watch 和 Parser 被调用,但是 Formatters/Render 永远不会被再次调用。
所以我的分钟确实得到更新并传播到更改模型,但指令的 "internal" 小时 和 分钟 永远不会更新.
仅当我从外部对 ng-model 值进行更改时。
我不确定发生了什么,因为类似的指令都按预期工作。 :s
// Here is a shortened version
angular.module('TestApp', ['TestDirectives']);
angular
.module('TestDirectives', [])
.directive("rangeMinutes", [function RangeMinutesDirective () {
return {
require: 'ngModel',
replace: true,
scope: true,
templateUrl: 'minutesHoursRange.html',
link: function (scope, element, attributes, ngModelCtrl) {
ngModelCtrl.$formatters.push(function (modelValue) {
var totalMinutes = (modelValue ? modelValue : 0);
return {
totalMinutes : totalMinutes,
hours : Math.floor(totalMinutes/60),
minutes : parseInt(totalMinutes%60, 10)
};
});
ngModelCtrl.$render = function () {
if (!ngModelCtrl.$viewValue) {
ngModelCtrl.$viewValue = {
hours: 0, minutes: 0, totalMinutes: 0
};
}
scope.totalMinutes = ngModelCtrl.$viewValue.totalMinutes;
scope.hours = Math.floor(scope.totalMinutes/60);
scope.minutes = parseInt(scope.totalMinutes%60, 10);
};
scope.$watch('totalMinutes', function () {
ngModelCtrl.$setViewValue({
totalMinutes: scope.totalMinutes,
hours: scope.hours,
minutes: scope.minutes
});
});
ngModelCtrl.$parsers.push(function (viewValue) {
return parseInt(viewValue.totalMinutes, 10);
});
}
};
}])
.controller("TestController", ["$scope", function ($scope) {
$scope.testObject = { testValue: 40 };
}]);
指令模板:
<div class="form-inline minutesHoursRange">
<div class="form-group">
<label>
<input type="range" min="0" max="100" step="1" class="form-control"
data-ng-model="totalMinutes"/> {{hours}} hrs {{minutes}} mns
</label>
</div>
</div>
查看:
<body data-ng-app="TestApp" data-ng-controller="TestController">
<div data-ng-model="testObject.testValue" data-range-minutes></div>
</body>
您没有 $watch
超过 totalMinutes
属性,只需添加:
scope.$watch('totalMinutes', function domToViewValue () {
scope.hours = Math.floor(scope.totalMinutes/60),
scope.minutes = parseInt(scope.totalMinutes%60, 10);
});
一切正常。
我写了一个很简单的 directive 转分钟 进入范围滑块,并在其旁边显示 小时 和 分钟。 问题是移动范围滑块确实会更新范围, 所以 Watch 和 Parser 被调用,但是 Formatters/Render 永远不会被再次调用。
所以我的分钟确实得到更新并传播到更改模型,但指令的 "internal" 小时 和 分钟 永远不会更新.
仅当我从外部对 ng-model 值进行更改时。
我不确定发生了什么,因为类似的指令都按预期工作。 :s
// Here is a shortened version
angular.module('TestApp', ['TestDirectives']);
angular
.module('TestDirectives', [])
.directive("rangeMinutes", [function RangeMinutesDirective () {
return {
require: 'ngModel',
replace: true,
scope: true,
templateUrl: 'minutesHoursRange.html',
link: function (scope, element, attributes, ngModelCtrl) {
ngModelCtrl.$formatters.push(function (modelValue) {
var totalMinutes = (modelValue ? modelValue : 0);
return {
totalMinutes : totalMinutes,
hours : Math.floor(totalMinutes/60),
minutes : parseInt(totalMinutes%60, 10)
};
});
ngModelCtrl.$render = function () {
if (!ngModelCtrl.$viewValue) {
ngModelCtrl.$viewValue = {
hours: 0, minutes: 0, totalMinutes: 0
};
}
scope.totalMinutes = ngModelCtrl.$viewValue.totalMinutes;
scope.hours = Math.floor(scope.totalMinutes/60);
scope.minutes = parseInt(scope.totalMinutes%60, 10);
};
scope.$watch('totalMinutes', function () {
ngModelCtrl.$setViewValue({
totalMinutes: scope.totalMinutes,
hours: scope.hours,
minutes: scope.minutes
});
});
ngModelCtrl.$parsers.push(function (viewValue) {
return parseInt(viewValue.totalMinutes, 10);
});
}
};
}])
.controller("TestController", ["$scope", function ($scope) {
$scope.testObject = { testValue: 40 };
}]);
指令模板:
<div class="form-inline minutesHoursRange">
<div class="form-group">
<label>
<input type="range" min="0" max="100" step="1" class="form-control"
data-ng-model="totalMinutes"/> {{hours}} hrs {{minutes}} mns
</label>
</div>
</div>
查看:
<body data-ng-app="TestApp" data-ng-controller="TestController">
<div data-ng-model="testObject.testValue" data-range-minutes></div>
</body>
您没有 $watch
超过 totalMinutes
属性,只需添加:
scope.$watch('totalMinutes', function domToViewValue () {
scope.hours = Math.floor(scope.totalMinutes/60),
scope.minutes = parseInt(scope.totalMinutes%60, 10);
});
一切正常。