我在使用angular.js创建一个click-to-edit指令时遇到了一个奇怪的问题:
模型在表单提交时更新,但更新的模型未在以下http.post中使用,旧的使用旧模型。
例如,在表格中:如果我将第一条记录的“note”字段从“secret”编辑为“myNote”,则bowsers控制台会将“myNote”显示为我项目的comment属性的值,但服务器仍然收到“秘密”。
为了证明这一点,我在github上创建了一个小例子:https://github.com/madmarkus/angular.js-Sample 我将尝试在此处仅显示相关代码。
我的控制器看起来像
function ListCtrl($scope, $http) {
$http.get('./items.json').success(function (data) {
$scope.items = data;
}).error(
function(){
console.log("Failed to load items.");
});
$scope.saveEditor = function () {
$scope.saveItem(this.item);
};
$scope.saveItem = function (w) {
console.log("Attempt to safe: ");
console.log(w);
$http.post("http://localhost:8888", w, {}).success(function () {
console.log("post successfully sent");
}).error(function (data, status, headers, config) {
console.log("Error on save.");
});
};
}
和app.js一样
app = angular.module('planner', []).
config(['$routeProvider', function ($routeProvider) {
$routeProvider.
when('/items', {templateUrl: 'item-list.html', controller: ListCtrl}).
otherwise({redirectTo: '/items'});
}]);
app.directive("clickToEdit", function() {
var editorTemplate = '<div>' +
'<div ng-hide="view.editorEnabled" ng-click="enableEditor()" class="editable" ' +
'style="width: 100%; min-height: 1.5em; display:inline-block" >' +
'{{value}} ' +
'</div>' +
'<form ng-show="view.editorEnabled">' +
'<input ng-model="view.editableValue"><br />' +
'<button class="btn" ng-click="save()" type="submit">Save</button>' +
' or ' +
'<a ng-click="disableEditor()">cancel</a>.' +
'</form>' +
'</div>';
return {
restrict: "A",
replace: true,
template: editorTemplate,
scope: {
value: "=clickToEdit",
saveCallback: "&saveFunction"
},
controller: function($scope) {
$scope.view = {
editableValue: $scope.value,
editorEnabled: false
};
$scope.enableEditor = function() {
$scope.view.editorEnabled = true;
$scope.view.editableValue = $scope.value;
};
$scope.disableEditor = function() {
$scope.view.editorEnabled = false;
};
$scope.save = function() {
$scope.value = $scope.view.editableValue;
$scope.disableEditor();
$scope.saveCallback();
};
}
};
});
如上所述,当我使用click&amp; edit将第一条记录的音符值从secret更改为myNote时,bowser和控制台中的js调试器显示正确的编辑后值:
[22:24:20.026] Attempt to safe:
[22:24:20.026] ({id:"977", datetime:"21.07.2013 10:00", note:"myNote", remark:"important", comment:"editme", $$hashKey:"004"})
但是服务器仍然收到“旧”值:
Received body data:
{"id":"977","datetime":"21.07.2013 10:00","note":"secret","remark":"important","comment":"editme"}
从我发现和阅读的内容来看,这可能是我面临的一个范围问题,但我无法找到正确的方法来处理它。还使用$ scope。$ apply()...
任何提示?
对代码的任何评论也非常感谢; - )
非常感谢
Markus
答案 0 :(得分:1)
你有时间问题。您需要知道,当您要打印的对象发生更改时,chrome会更新console.log中的消息。
当你的指令调用回调时,它没有更新你绑定的值。您可以通过添加带有chrome的断点来看到这一点(将它们放在console.log调用上)。这个问题的一个快速解决方案是在$ timeout内调用回调函数,因为它会导致执行另一个摘要,然后你知道值已经更新了:
controller: function($scope, $timeout) {
//...
$scope.save = function() {
$scope.value = $scope.view.editableValue;
$scope.disableEditor();
$timeout(function() {
$scope.saveCallback();
});
};
}