1

我在使用 angular.js 创建点击编辑指令时遇到了一个奇怪的问题:

模型在表单提交时更新,但更新后的模型没有在后面的 http.post 中使用,而是使用旧的。

例如,在一个表格中:如果我将第一条记录的“note”字段从“secret”编辑为“myNote”,bowsers 控制台将显示“myNote”作为我的项目的评论属性的值,但服务器仍然收到“秘密”。

为了证明这一点,我在 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&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()...

有什么提示吗?

对代码的任何评论也非常感谢;-)

非常感谢

马库斯

4

1 回答 1

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();
        });
    };
}
于 2013-07-24T00:15:21.903 回答