ngRepeat 模型更改后不更新 [英] ngRepeat not updating after model changed

查看:18
本文介绍了ngRepeat 模型更改后不更新的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试编写一些搜索输入,以便使用 ngResource 从数据库中获取数据.

页面中显示的数据带有 ng-repeat,但是当我进行搜索并且 $scope 已更新时,视图未更新并显示旧数据.

代码如下:

main.html(活动视图)

<form class="form-inline search-form col-md-offset-1"><div class="form-group col-md-5"><label class="sr-only" for="search_location">Location</label><输入id="search_location" type="search" class="form-control"ng-Autocomplete ng-model="place" placeholder="Location"/>

<div class="form-group col-md-5"><label class="sr-only" for="search_tags">标签</label><输入样式=宽度:100%;"id="search_tags" 类型="搜索"class="form-control" id="search_tags" placeholder="Tags">

<div class="col-md-1"><md-button class="md-fab md-mini" aria-label="搜索" ng-click="searchCtrl.search()"><md-icon class="md-fab-center"md-font-icon="glyphicon glyphicon-search" style="color: black;"></md-icon></md-button>

</表单>

<div ng-controller="mainCtrl"><div ng-repeat="eventi 中的事件" ng-include="'views/components/event_card.html'" class="col-md-3"></div>

main.js

'use strict';app.factory('Eventi', function($resource) {return $resource('/eventsws/events/:location', {location : '@location'}, {搜索: {方法:'获取',参数:{位置":@location"},isArray : 真}})});app.controller('mainCtrl', function($scope, Eventi) {$scope.eventi = Eventi.query();});

searchbar.js

'use strict';app.controller('searchCtrl', function($scope, Eventi) {$scope.place = null;this.search = 函数(){$scope.eventi = Eventi.search({位置":$scope.place});}});

当它启动时,它从数据库中获取所有数据并正确显示它们,当我尝试进行搜索时,$scope.eventi 被更新(我可以从调试中看到 $scope.eventi 中的新数据)但视图仍然显示旧数据,永远不会更新.

我尝试在搜索功能的末尾使用 $scope.$apply 但结果是一样的.

你知道为什么它不起作用吗?

感谢您的时间.

解决方案

您在调试中看到的 $scope.eventi 是 searchCtrl 中的那个,而不是 mainCtrl 中的那个.要更新 mainCtrl $scope.eventi,您必须找到其他方法.

一个简洁但冗长的解决方案是使用服务在控制器中共享变量.

在评论中回答问题:

<块引用>

我可以看到它更新了,但视图仍然显示旧数据

我猜有什么问题(即使我实际上没有看到您的代码).

问题

如果你像这样绑定你的 var :

服务

<代码>[...]service.serviceVar = 1;退货服务[...]

这将创建一个带有引用的1"var.

控制器

<代码> [...]$scope.myvar = Service.serviceVar;[...]

这会将 $scope.myvar 绑定到1"引用.

如果您在您的服务或其他控制器中执行此操作:

 service.serviceVar = 2;

您将创建一个带有新引用的新变量2",并将此引用分配给 service.serviceVar.糟糕的是,您对旧 1 变量的所有旧引用都不会更新.

解决方案

为了避免那样做:

服务

<代码>[...]service.servicevar = {};service.servicevar.value = 1;退货服务[...]

您使用新引用创建一个对象并将其分配给 servicevar.您创建一个变量1"并将其分配给 servicevar.value.

控制器

<代码>[...]$scope.myvar = Service.servicevar;[...]

您将 servicevar 引用分配给您的作用域变量.

查看

{{myvar.value}}

您可以通过使用 var 的属性来使用该值.

更新变量这样做:

service.servicevar.value = 2;

您将使用新引用创建一个新变量2",并用此引用替换旧引用.

但是这次您将所有对 servicevar 的引用保留在控制器中.

我希望我说的很清楚并且回答了你的问题.

尽量不要使用 $scope.$apply.这是一个非常糟糕的做法.如果你用它来做一些事情,你可能应该找到另一个来做这件事(我猜这对 Stacks 来说是一个很好的问题:为什么我需要 $apply 来解决我的问题 XXXXX")

rsnorman15 关于异步调用的使用有一个很好的观点.也看看他的回答.

这是我的一个老plunker使用服务共享属性

I'm tring to code a little search input to get data from a database using ngResource.

the data are shown in the page with a ng-repeat, but when i do the search and the $scope has been updated, the view is not updated and show old data.

Here is the code:

main.html (active view)

<div ng-controller="searchCtrl as searchCtrl" layout="column">
    <form class="form-inline search-form col-md-offset-1">
        <div class="form-group col-md-5">
            <label class="sr-only" for="search_location">Location</label> <input
                id="search_location" type="search" class="form-control"
                ng-Autocomplete ng-model="place" placeholder="Location" />
        </div>
        <div class="form-group col-md-5">
            <label class="sr-only" for="search_tags">Tags</label> <input
                style="width: 100%;" id="search_tags" type="search"
                class="form-control" id="search_tags" placeholder="Tags">
        </div>

        <div class="col-md-1">
            <md-button class="md-fab md-mini" aria-label="Search" ng-click="searchCtrl.search()"> <md-icon class="md-fab-center"
                md-font-icon="glyphicon glyphicon-search" style="color: black;"></md-icon>
            </md-button>
        </div>
    </form>
</div>

<div ng-controller="mainCtrl">

    <div ng-repeat="evento in eventi" ng-include="'views/components/event_card.html'" class="col-md-3"></div>

</div>

main.js

'use strict';
app.factory('Eventi', function($resource) {
    return $resource('/eventsws/events/:location', {location : '@location'}, { 
        search: {
            method: 'GET',
            params: {
                'location' : "@location"
            },
            isArray : true
        }
    })
});

app.controller('mainCtrl', function($scope, Eventi) {
    $scope.eventi = Eventi.query();
});

searchbar.js

'use strict';
app.controller('searchCtrl', function($scope, Eventi) {
    $scope.place = null;

    this.search = function() {

        $scope.eventi = Eventi.search({
            'location' : $scope.place
        });
    }
});

when it start it get all the data from the database and display them correctly, when i try to make a search, the $scope.eventi is updated (i can see the new data in $scope.eventi from the debug) but the view still show the old data and never update.

I've tried to use $scope.$apply at the end of the search function but the result is the same.

Have you any idea why it's not working?

Thanks for your time.

解决方案

The $scope.eventi you see in the debug is the one in your searchCtrl and not the one from your mainCtrl. To update your mainCtrl $scope.eventi you have to find an other way.

A clean but long solution would be using services to shares variables in your controllers.

To answer the question in comments :

i can see it updated, but the view still show the old data

I guess what's the problem (even if i actually didn't see your code).

Problem

If you bind your var like this :

Service

[...]
service.serviceVar = 1;
return service
[...]

This will create a "1" var with a reference.

Controller

  [...]
  $scope.myvar = Service.serviceVar;
  [...]

This will bind $scope.myvar to the "1" reference.

If you do this in your service or in an other controller :

   service.serviceVar = 2;

You will create a new var "2" with a new reference and you will assign this reference to service.serviceVar. Badly all your old references to the old 1 var will not update.

Solution

To avoid that do it like this :

Service

[...]
service.servicevar = {};
service.servicevar.value = 1;
return service
[...]

You create an object with a new reference and assign it to servicevar. You create a var "1" and assign it to servicevar.value.

Controller

[...]
$scope.myvar = Service.servicevar;
[...]

You assign the servicevar reference to your scope var.

view

{{myvar.value}}

You can use the value by using the property of your var.

Updating the var doing this :

service.servicevar.value = 2;

You will create a new var "2" with a new reference and replace the old reference by this one.

BUT this time you keep all your references to servicevar in your controllers.

I hope i was clear and it answer your question.

EDIT :

Try to never ever use $scope.$apply. It's a really bad practice. If you use that to make something works, you should probably find an other to do that (And it will be a great question for Stacks i guess : "Why do i need $apply to solve my problem XXXXX")

rsnorman15 has a good point about your uses of asynchronous calls. Take a look at his answer too.

Here is one of my old plunker using a service to share properties

这篇关于ngRepeat 模型更改后不更新的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
其他开发最新文章
热门教程
热门工具
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆