如何以 Angular 方式将更新的对象从服务发送到指令控制器函数?

How to send updated object from Service into Directive Controller function the Angular way?

我知道我缺少 AngularJS 正确执行此操作的方法。

mouseover 上,在我的 tagsPanel 视图中,我捕获了标签对象并首先将其发送到我的 tagsPanel 控制器中:

tagsPanel.html

<ul>
    <li ng-repeat="(k, m) in tags"
        ng-mouseover="hoverTag(m)"
        ng-mouseleave="leaveTag(m)">
        <div class="tag">{{m.term}}</div>
        <tags-hover ng-model="m"></tags-hover>
    </li>
</ul>

tags面板控制器:

vs.hoverTag = function(tagObj) {
    TagDetailsFactory.saveTagDetails(tagObj);
};

tagDetailsFactory 我工厂的最后一步是我关心的:

tagsHover = ScopeFactory.getScope('tagsHover');
tagsHover.hoveringTag(tag);

完整工厂代码:

(function() { "use strict";
    angular.module('tagDetailsFactory', [])
    .factory('TagDetailsFactory', [
        'ApiFactory',
        'ScopeFactory',
        function(ApiFactory,
                 ScopeFactory) {

        // Init ScopeFactory:
        // ------------------
        var tagsHover = {};

        return {
            saveTagDetails : saveTagDetails
        };

        ////////////////////////////////////////////////////////////////////////

        function saveTagDetails(tag) {

            if (tag.percent != undefined) {
                var conditional = tag.percent.toString().charAt(0);
                tag.direction = returnDirection(conditional);
            }

            function floorFigure(figure, decimals) {
                if (!decimals) decimals = 2;
                var d = Math.pow(10, decimals);
                return (parseInt(figure * d)/d).toFixed(decimals);
            };

            ApiFactory.getTagData(tag.term_id).then(function(data) {

                /*
                    Ton of tag updating code here

                    // Algorithm to get percentage change:
                    increase = tag.quantity - tag.previous_quantity;
                    increase = increase / tag.previous_quantity * 100;
                    increase = floorFigure(increase, 2);

                    etc etc...
                 */
                tagsHover = ScopeFactory.getScope('tagsHover');
                tagsHover.hoveringTag(tag);
            });
        };
    }]);
})();

^ 正如您在上面看到的,我粗略地获取了 tagsHover 指令的范围,然后在其中定位一个函数并传递更新的 tag 对象。


下面是我的整个tagHoverDirective标记,理想的Angular方式是怎样通过的更新后的标签对象进入 tagHoverDirective 函数 hoveringTag?

(function() { "use strict";

    angular.module('tagHoverDirective', [])

    .directive('tagsHover', function() {
        return {
            templateUrl : "tags/tagsHover.html",
            restrict    : "E",
            replace     : true,
            link: function($scope, el, attrs) {
                // console.debug($scope, attrs);
            },
            scope:{
                tag:'=ngModel'
            },
            controller  : ['$scope',
                           'ScopeFactory',
                           'TagDetailsFactory',
                           function($scope,
                                    ScopeFactory,
                                    TagDetailsFactory) {

                // Init tagsHover scope:
                // ---------------------
                var vs = $scope;
                    ScopeFactory.saveScope('tagsHover', vs);

                vs.hoveringTag = function(t) {
                    t.tagsHoverDisplay = true;
                };

                vs.leavingTag = function(t) {
                    t.tagsHoverDisplay = false;
                };
            }]
        }
    });
})();

tagHover.html

的标记
<div class="tags-hover-container" ng-show="tag.tagsHoverDisplay">
    <div class="tag-info-padding">
        <div class="tweets" ng-hide="!tag.quantity">
            <div class="percentage" ng-hide="tag.length">
                {{tag.tweet_percentage}}%
            </div>
            <div class="tweet-count">{{tag.quantity}} tweets</div>
        </div>

        <div class="tweets-direction" ng-show="!tag.quantity">
            0 tweets
        </div>
    </div>
</div>

我整理了一个基本示例,该示例根据感兴趣的标记类型通过回调通知指令更新。我放入了三个文本字段,标识符文本字段才是真正重要的。

首先是标记,它只是一个空指令,其模板最初将在没有标记数据的情况下呈现,表单将在我们将要存储的值中标记。

<sample-directive></sample-directive>


<form ng-submit="addNewTag()">

    <input placeholder="tag type identifier" type="text" ng-model="tag.tagIdentifier">
    <input placeholder="tag name" type="text" ng-model="tag.tagName">
    <input placeholder="tag message" type="text" ng-model="tag.tagMessage">
    <input type="submit" value="Add new tag">

</form>

添加标签的控制器

.controller('mainCtrl',function($scope, sampleService) {

$scope.tag = {
    tagName: "",
    tagIdentifier: "",
    tagMessage: ""
}

$scope.addNewTag = function() {
    var tag = {};

    tag.message = $scope.tag.tagMessage;
    tag.name = $scope.tag.tagName;

    sampleService.setTag(tag, $scope.tag.tagIdentifier);

}

})

主要思想在这里

.directive('sampleDirective', function(sampleService) {

return {
    restrict: 'E',
    link: function(scope, iElement, iAttrs) {

        sampleService.registerTagCallback("tagsHover",tagCallback);

        function tagCallback(tag) {
            scope.tag = tag;
        }

    },
    template: "<div>{{tag.message}}</div>"
}

})

该指令(当它被注册并且它的 link 功能被激活时)将使用该服务来注册一个回调,当您从该工厂内部设置标签时,该回调应该在您的工厂内部执行。可以这样做

.service('sampleService', function() {


return {
    setTag: setTag,
    registerTagCallback, registerTagCallback
}

var callbacks;
var tags;

function setTag(tag, identifier) {
    if (!tags || tags.length == 0)
        tags = [];

    tags.push({
        tag: tag,
        identifier: identifier
    });


    angular.forEach(callbacks, function(callback) {

       if (callback.identifier == identifier) {
          callback.method(tag);
       }

    });


}


function registerTagCallback(identifier, callback) {

    if (!callbacks || callbacks.length == 0)
        callbacks = [];

    callbacks.push({
        identifier: identifier,
        method: callback
    });

}

}) 

每次设置标签时,您都会检查已注册的回调以查看是否有人有兴趣接收该标签,并使用传入的标签调用该回调。该指令然后从已注册的回调内部更新其范围函数参数

这是我整理的 fiddle 和一个工作示例。标签标识符需要匹配指令回调标识符(在本例中为 "tagsHover"),然后您应该看到指令更新为标签

的名称和消息

https://jsfiddle.net/5c88pte6/4/