ng-repeat在模型更改后不再更新

时间:2015-12-25 12:05:16

标签: javascript angularjs

我有两个控制器,一个用于我的表单,另一个用于显示文档 所以,我想在用户提交表单后更新记录列表,因为我创建了一个服务并在两个控制器之间共享一个变量:

accountingApp.factory('sharedProperties', function () {
   var shareableData = []

   return {
      getProperty: function (property) {
         return shareableData[property];
      },
      setProperty: function(property, value) {
         shareableData[property] = value;
      }
   };
});

要获取文档,我设置了服务中的accDocs,然后将其附加到vm.accDocs以及稍后的html上,使用它ng-repeat="accDoc in vm.accDocs"

function accDocsController(api, sharedProperties) {
  var vm = this;

  sharedProperties.setProperty("accDocs", api.getAccDocs(vm));
  vm.accDocs = sharedProperties.getProperty("accDocs");
}

在形式的控制器中,这就是:

vm.submit = function(vm) {
     if (vm.entryForms.$valid) {
        api.newAccDoc(...);

        console.log(sharedProperties.getProperty("accDocs")); // returns the actual array
        sharedProperties.setProperty("accDocs", null);
        console.log(sharedProperties.getProperty("accDocs")); // returns null
     }
  };

提交表单后,文档不会消失。我可以使用ng-inspector记录vm.accDocs并查看其中仍然存在的对象。

我的问题在哪里?

3 个答案:

答案 0 :(得分:2)

这种情况正在发生,因为您正在替换该值。因此vm.accDocs绑定到原始值,而工厂现在包含新值。您可以通过将工厂状态数据包装在父对象中并绑定到该对象来轻松解决此问题。例如:

accountingApp.factory('sharedProperties', function () {
    var state = {
        shareableData: []
    };

    return {
        getState: function(){
            return state;
        },
        setProperty: function(property, value) {
            state.shareableData[property] = value;
        }
    };
});

然后,不是直接绑定到您想要的值,而是绑定到状态本身,并使用.引用所需的值。例如:

vm.accDocsState = sharedProperties.getState();

和HTML(可能不正确,因为我看不到你的代码,但希望你明白了):

ng-repeat="accDoc in vm.accDocsState.accDocs"

答案 1 :(得分:1)

问题在于 sharedProperties.setProperty()函数中的 accDocsController

// api.getAccDocs(vm) is undefined at this moment
sharedProperties.setProperty("accDocs", api.getAccDocs(vm));

您正在使用服务 api.getAccDocs(vm),该服务使用http请求获取数据。 (如果我错了,请纠正我。)

您应该从此服务返回一个承诺,这样您就可以在实际存在时传递数据。

解决方案:

api-service 中注入Angular's $q service

服务(api)

您的服务应如下所示:

var API = {};

function getAccDocs(vm) {

    var deferred = $q.defer();

    $http.get("http://yourapi.com")
        .then(function onGotAccDocs(response) {
            // response = [{...}, {...}]
            deferred.resolve(response);
        }, function onGetAccDocsFailed(error) {
            deffered.reject(error);
        });

    return deferred.promise;
}

API.getAccDocs = getAccDocs;

控制器(accDocsController) 请稍微修改您的控制器:

function accDocsController(api, sharedProperties) {

    var vm = this;

    function initialize() {

        api.getAccDocs(vm)
            .then(function onGotAccDocs(response) {
                console.info('AccDocs retrieved succesfully!', response);

                // Now we can set sharedProperties 'accDocs' since we've got data!
                sharedProperties.setProperty("accDocs", response);
                vm.accDocs = sharedProperties.getProperty("accDocs");

            }, function onGetAccDocsFailed(error) {
                console.error('Could not retrieve accDocs', error);
            });

    }


    // --- Initialize ---
    initialize();

}

答案 2 :(得分:0)

如果在术语“提交”中你意味着将表单发布到服务器然后返回初始视图,那么你重新加载页面,如果你的两个控制器都位于同一页面上,那么它们也会被重新创建,并且accDocs在accDocsController构造函数中初始化。