以下是一个例子:
http://plnkr.co/edit/ezTUdoDKhCUGX3848VLp
HTML:
<p>Hello {{data | json}}!</p>
<div>
<textarea myconverter ng-model="data"></textarea>
</div>
JavaScript:
var app = angular.module('plunker', ['ngResource']);
app.controller('MainCtrl', function($scope, $resource) {
$scope.data = $resource('some-data.json').get({});
})
.directive('myconverter', function() {
return {
restrict: 'A',
require: 'ngModel',
link: function(scope, element, attr, ngModel) {
function fromJson(json) {
var out = JSON.stringify(json, null, 2);
return out;
}
function toJson(text) {
return JSON.parse(text);
}
ngModel.$parsers.push(toJson);
ngModel.$formatters.push(fromJson);
}
};
})
;
简单的Hello部分工作正常,当AJAX调用返回时,它会使用正确的数据进行更新。但textarea永远不会更新。如果我设置了一个断点,它似乎给了一个没有数据的对象(但我可以看到$ resource方法)。如果我将textarea更改为指向“data”对象的字段,它将按预期工作。
答案 0 :(得分:0)
我遇到了同样的问题并找到了fix(至少是最新的Angular)。
正如Glav所述,ngModel
观察者未被触发。这是because Angular's modelWatch is just checking for object identity。为了防止这种情况,我复制了(稍微修改过)之后出现的来源。现在我们有一个新的directive
,我们可以插入ngModels
$resource
。我可能会更新这个,以便有一个可配置的&#34;待定&#34;消息/指令(以及正确的priority
设置),稍后。
app.directive('isResourceModel', function() {
return {
restrict: 'A',
require: 'ngModel',
link: function(scope, element, attr, ctrl) {
ctrl.$formatters.push(function resourceFormatter(value){
if (value.$promise != null && value.$resolved === false){
value.$promise.then(function (data){
var viewValue = data,
idx = ctrl.$formatters.length,
runFormatter = false;
while(idx--){
formatter = ctrl.$formatters[idx];
if (runFormatter
|| (runFormatter = formatter === resourceFormatter))
viewValue = formatter(viewValue)
}
ctrl.$viewValue = viewValue;
ctrl.$render();
if (ctrl.$validators.length > 0)
ctrl.$validate();
});
}
return value;
});
}
};
});
编辑:我的答案是module。你可以像bower
一样使用它:
bower install https://github.com/P-Seebauer/ng-isFutureModel.git
答案 1 :(得分:-2)
该问题与您的指令无关。在您的控制器中,使用$ http服务替换$ resource的使用(显然在控制器依赖项中包含$ http):
$scope.data = $http({
url:'some-data.json',
method:"GET"
}).then(function(result) {
$scope.data = result.data;
});
无论出于何种原因,当$ resource将调用的结果分配给作用域上的'data'时,不会触发监视,因此当$ resource完成时,textarea的模型不会更新,所以最初$ scope.data是text和{}显示在文本区域,进行$ resource调用,$ scope.data更新,但是textarea watch没有启动。使用$ http服务并手动将调用结果分配给$ scope.data确实有效,并触发相应的$ watch。
你可以通过添加
来看到这一点$scope.$watch('data',function() {....});
在你的控制器的某个地方,当使用$ resource时,你会看到手表最初只调用一次。 $ resource调用完成后,$ watch永远不会被触发。