AngularJS指令不会更新

时间:2014-12-23 18:17:06

标签: javascript angularjs angularjs-directive

我使用Angular开发了一个论坛,您可以标记每个讨论。在讨论列表中,如果您单击标记,它将使用此标记过滤讨论。

我使用指令显示标记:

directive('tag', function(){
    return {
        restrict: 'AE',
        templateUrl: tagDirective,
        controller: 'TagController',
        controllerAs: 'tagCtrl',
        scope: {
            tagId: '@id'
        },
        replace:true
    }
})

模板:

<div class="tag" ng-click="tagCtrl.filterByTag(tagId)">
    {{ tagCtrl.tags[tagId].title }}
</div>

控制器:

controller("TagController", ["TagService", "ModelService", "$location", function(tag, model, $location){
    var ctrl = this;
    ctrl.tags = {};
    ctrl.tag = tag;

    model.getTags(function(datas){
        datas.forEach(function(item){
            ctrl.tags["tag"+item.id] = item;
        });
    });

    ctrl.filterByTag = function(id){
        tag.current = ctrl.tags[id];
        if($location.path() !== routes.index){
            $location.path(routes.index);
        }
    };
}])

服务:

service('TagService', [function(){
    var serv = this;
    serv.current = {};
}])

每当在论坛中,当用户点击某个标签时,他就会被重定向到索引页面(所有讨论的列表)。

使用的过滤标签“存储”在服务中。

所有这一切似乎都有效:我可以显示存储的标签,当我点击一个标签时,我被重定向(过滤不起作用,但是打赌这是另一个问题)。

我的问题是我想在标题中显示标记:

<tag id="{{ 'tag'+headerCtrl.tag.current.id }}"></tag>

标题永远不会显示标记标题。

我试过了:

<tag id="{{ 'tag2' }}"></tag>

强制显示第二个标签(不是过滤,只显示),它也不起作用......

我做错了吗?

子公司:我是否以正确的方式使用AngularJS?是否有一些我没有使用或被误解的最佳实践?

谢谢!

编辑1:

我有标题部分:

指令:

directive("forumHeader", function(){
    return {
        restrict: 'AE',
        templateUrl: headerDirective,
        controller: 'HeaderController',
        controllerAs: 'headerCtrl',
        replace:true
    };
})

Html:

<header>
    <tag tid="{{ 'tag'+headerCtrl.tag.current.id }}"></tag>
</header>

控制器:

controller("HeaderController", ["TagService", "ModelService", function(tag, model){
    var ctrl = this;
    ctrl.tag = tag;
    ctrl.tags = [];

    model.getTags(function(datas){
        ctrl.tags = datas;
    });

    ctrl.colored = function(item){
        if(item.color) return true;
    };
}])

2 个答案:

答案 0 :(得分:0)

指令控制器会注入一个范围和一个元素。你没有注射那些。您可以从$scope.tagId获取属性值(并在模板中使用它)。

答案 1 :(得分:0)

我找到了一个肮脏的解决方案......

问题在于:

model.getTags(function(datas){
    datas.forEach(function(item){
        ctrl.tags["tag"+item.id] = item;
    });
});

并且在应用程序的节奏中。对于服务,如果API调用正在运行,我将返回稍后将填充的空数组。但在这里,我在服务数组和控制器数据结构之间做了区别。它不适用于Tag标头,因为API调用正在运行,因此数组为空。

为了解决这个问题,我在第一次尝试存储在控制器和$ scope中。$监视API调用的返回数据并在watch回调中的控制器对象中重新分配,但回调只被调用一次而不是在更新阵列时。

所以我做了第二个Service函数(getTagsObject),它返回一个直接存储在控制器中的对象。它有效,但我认为它不是很干净。

问题来自我的服务,而不是来自我在这里展示的代码,对不起是混乱。这是服务的代码:

serv.getTags = function(callback){
    callback = callback || function(){};
    var tag;
    if(serv.tags.length === 0 && !tagsIndex["_running"]){
        tagsIndex["_running"] = true;
        $http.get(tagReadAll)
            .success(function(data){
                data.forEach(function(item){
                    initTag(item);
                });
                callback(serv.tags);
                tagsIndex["_running"] = false;
            })
            .error(function(data){
                tagsIndex["_running"] = false;
            });
    } else {
        callback(serv.tags);
    }
};

serv.getTagsObject = function(callback){
    if(serv.tags.length === 0) serv.getTags();
    callback(serv.tagsObj);
};

和initTag函数:

function initTag(data){
    var tag = $.extend({}, data);
    tagsIndex[tag.id] = tag;
    serv.tagsObj["tag"+tag.id] = tag;
    serv.tags.push(tag);
    return tag;
}