javascript 如果通过 ajax 填充范围,AngularJS 指令模板不会更新

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/14984777/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-26 23:03:56  来源:igfitidea点击:

AngularJS directive template not updating if scope is populated via ajax

javascriptangularjs

提问by Andrea Aloi

I tried to give this question as precise a title as I could.
I'm pretty new to AngularJS but I'm stomped on this issue. I tried to make a jsfiddle to better illustrate my issue but it relies on too many separate files. And alas it is not online yet, so bear with the verbosity. :)

So basically I have an app I built with yeoman init angular, and my app.jslooks like this:

我试图给这个问题尽可能精确的标题。
我对 AngularJS 还很陌生,但我在这个问题上被踩到了。我试图制作一个 jsfiddle 来更好地说明我的问题,但它依赖于太多单独的文件。可惜它还没有上线,所以请忍受冗长。:)

所以基本上我有一个用我构建的应用程序yeoman init angular,我的app.js外观是这样的:

"use strict"

var myApp = angular.module("myApp", [])
.config(function($routeProvider) {
    $routeProvider
    .when("/lineup", {
        templateUrl: "views/lineup.html",
        controller: "LineupCtrl"
    })
    //other routes
    .otherwise({
        redirectTo: "/"
    });
})
.directive("playerlist", function() {
    return {
        restrict: "E",
        transclude: false,
        scope : {},
        templateUrl : "views/directives/playerlist.html",
        controller : function($scope) {
            $.get("/players")
            .success(function(players) {
                $scope.players = players;
            });
        },
        replace : true
    }
});

My index.htmlpicks up app.jsand has an anchor that references #/lineup, which effectively opens views/lineup.html; to simplify things, let's assume the latter only contains the (custom) <playerlist></playerlist>tag.
Inside the directive's controller function I'm sure that $.get("/players")works as it should because I can see from chrome's network tab that the response comes through correctly as an array of players.
Finally, my views/directives/playerlist.htmlhas the code that replaces the <playerlist>tag, which follows:

index.html拿起app.js并有一个引用的锚点#/lineup,它有效地打开views/lineup.html;为了简化事情,让我们假设后者只包含(自定义)<playerlist></playerlist>标签。
在指令的控制器函数中,我确信它$.get("/players")可以正常工作,因为我可以从 chrome 的网络选项卡中看到响应作为播放器数组正确传递。
最后,我views/directives/playerlist.html有替换<playerlist>标签的代码,如下所示:

<table class="table table-striped">
    <thead>
        <tr>
            <th>Name</th>
            <th>Age</th>
            <th>Role</th>
            <th>Strength</th>
        </tr>
    </thead>
    <tbody>
        <tr ng-repeat="player in players">
            <td>{{player.first_name}} {{player.last_name}}</td>
            <td>{{player.age}}</td>
            <td>{{player.role}}</td>
            <td>{{player.strength}}</td>
        </tr>
    </tbody>
</table>

My idea was to make the "playerlist" directive independent from LineupCtrlfor I might want to reuse it elsewhere in the project.
Ok so here goes: when I click on the anchor that loads #/lineupthe first time, the tbodyelement of the above table is empty (no rows appended to it); the funny thing is, when I click on it a second time, the table is correctly populated with the players I get with the $.get("/players")instruction. I suspect this is due to the slight lag that occurs between the rendering of playerlist.html and the $scope.players variable being assigned. But isn't that the whole point of an angular app? That when scope variables change the respective views (and their templates) are updated?
Please help!
Cheers,

Andrea

我的想法是让“playerlist”指令独立于LineupCtrl因为我可能想在项目的其他地方重用它。
好的,这里是:当我点击#/lineup第一次加载的锚点时,tbody上表的元素是空的(没有附加行);有趣的是,当我第二次点击它时,表格中正确填充了我根据$.get("/players")指令获得的球员。我怀疑这是由于 playerlist.html 的呈现和被分配的 $s​​cope.players 变量之间发生的轻微滞后。但这不是 Angular 应用程序的全部意义吗?当范围变量更改相应的视图(及其模板)时会更新吗?
请帮忙!
干杯,

安德里亚

回答by Yoshi

Whenever you update scope variables outside of an angular function, you need to tell angular that something changed. See scope.$apply.

每当您在 angular 函数之外更新范围变量时,您都需要告诉 angular 某些内容发生了变化。见scope.$apply

$.get("/players")
.success(function(players) {
   $scope.$apply(function () {
     $scope.players = players;
   });
});

On a different note, angular has a built in ajax service, so there is no need to use jQuery. A good explanation can be found in the tutorial: 5 - XHRs & Dependency Injection.

另一方面,angular 有一个内置的ajax 服务,所以不需要使用 jQuery。可以在教程:5 - XHRs & Dependency Injection 中找到一个很好的解释。