简体   繁体   English

AngularJS:具有动态数据的ng-repeat

[英]AngularJS: ng-repeat with dynamic data

I'm building a simple AngularJS app, but I couldn't solve a problem regarding services, ng-repeat and dynamically added data. 我正在构建一个简单的AngularJS应用程序,但无法解决有关服务,ng-repeat和动态添加数据的问题。

What I'm trying to do 我想做什么

My page is splitted into few countrollers. 我的页面被分成几个计数器。 In the homeController I have a text field and a button. homeController我有一个文本字段和一个按钮。 When I press the button I'm doing an API call to the server, the server returns JSON and I'm setting the data to Storage service. 当我按下按钮时,正在对服务器进行API调用,服务器返回JSON,并将数据设置为Storage服务。 In this part everything is OK - The server returns data as it should and the data is setted to the service and I'm getting console.log('Data set!'); 在这一部分中,一切正常-服务器按应有的方式返回数据,并将数据设置为服务,然后我得到console.log('Data set!'); in the Storage service. 在存储服务中。 In the second controller ( slidesController ) I'm having a ng-repeat 在第二个控制器( slidesController )中,我正在执行ng-repeat

<div ng-controller="slidesCtrl">
    <div ng-repeat="current in paragraphs"> test </div>
</div>

And as you can see in my code below, paragraphs is binded to Storage.data value in slidesCtrl 正如您在下面的代码中所见, paragraphs被绑定到slidesCtrl Storage.data

So, when a user enter something in the box and press the button (homeCtrl), the server should pass the returned data to Storage service and render the data using ng-repeat (slideCtrl). 因此,当用户在框中输入内容并按下按钮(homeCtrl)时,服务器应将返回的数据传递给Storage Service并使用ng-repeat(slideCtrl)呈现数据。 If I hardcode the data in Storage server with [2, 3, 4, 5] for example, everything is ok ( I'm getting test 4 times, because of ng-repeat ), but if the data is taken with api call, ng-repeat isn't working. 例如,如果我使用[2、3、4、5]在存储服务器中对数据进行硬编码,那么一切正常(由于ng-repeat,我进行了4次测试),但是如果数据是通过api调用获取的, ng-repeat不起作用。

Code

App.controller('homeCtrl', function ($scope, $http, Api) {...

    $scope.onprocess = function () {
        $scope.loading = true;

        Api(.....);
    }
});

App.controller('slidesCtrl', function ($scope, Storage) {


    $scope.paragraphs = Storage.data.paragraphs; // NOT WORKING IF DATA IS DYNAMICALLY ADDED

    $scope.paragraphs = Storage.test; // IF DATA IS PREDEFINED EVERYTHING IS FINE


});

App.factory('Api', function ($http, Storage) {
    return function (data) {
        $http.post('/api', {
            url: data.url,
            analyze: 0
        }).success(function (res) {....
            Storage.set(res);....
        }).error(function () {....
        });
    };
});

App.factory('Storage', function () {
    var output = {};

    var set = function (data) {
        output = data;
        console.log('Data set!');
    };

    return {
        set: set,
        data: output,
        test: [1, 2, 3]
    };
});

I found 我发现

angular.copy(data, output);

as solution. 作为解决方案。

You can see more information on this topic Sharing dynamic data between two controllers with service AngularJS 您可以查看有关此主题的更多信息, 并使用服务AngularJS在两个控制器之间共享动态数据。

Thanks to everyone. 谢谢大家。

I suspect that this is due to the lag in a AJAX call and angular executes the service before a AJAX call. 我怀疑这是由于在滞后AJAX调用和前角执行服务AJAX调用。 As none of the scopes are changing, angular is not detecting a change and hence its not reflecting on your 由于所有示波器都没有变化,角度不会检测到变化,因此不会反映在您的

Possible Solution 可能的解决方案

Use a getter in Storage service to get the paragraphs and call that getter method from slidesCtrl , like this. 在Storage服务中使用getter来获取段落,然后从slidesCtrl调用该getter方法,就像这样。

App.controller('slidesCtrl', function($scope, Storage) {
    $scope.paragraphs = Storage.getParagraphs();
});

And in your service, you can use it like this. 在您的服务中,您可以像这样使用它。

App.factory('Storage', function() {
    var output = {};

    var set = function(data) {
        output = data;
        console.log('Data set!');
    };

    return {
        set: set,
        getParagraphs: function () {
            return output && output.paragraphs;
        }
    };
});

The problem is with how you've defined your Storage service. 问题在于您如何定义Storage服务。

In the set function, you're assigning directly to the output local variable, which will not automatically update the data property of the object the factory returns. set函数中,您将直接分配给output局部变量,该变量不会自动更新工厂返回的对象的data属性。

To illustrate the problem: 为了说明问题:

var output = {foo: 1, bar: 2};
function set(somenewdata) {
  output = somenewdata;
}
var obj = {data: output};
// obj == {data: {foo: 1, bar: 2}}

set({baz: 3});

// output == {baz: 3}
// but, obj == {data: {foo: 1, bar: 2}}

So if you change your Storage service to something like: 因此,如果您将存储服务更改为以下内容:

App.service('Storage', function() {
  this.data = {};
  this.set = function(newdata) {
    this.data = newdata;
  };
});

When a controller binds a property to Storage.data , the data will actually be updated. 当控制器将属性绑定到Storage.data ,数据实际上将被更新。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM