AngularJS动态模板更新

时间:2016-02-04 23:36:01

标签: angularjs angularjs-directive angularjs-ng-repeat

我有一个我无权更新的AngularJS应用程序,但是我确实能够在页面加载/初始化后执行JavaScript。

我需要做的是更新组件标记中的一堆文本。但是我无法更新AngularJS转发器元素(相关项)中的内容,因为看起来Angular已经在页面初始化时将其编译为模板。

在哪里可以入侵范围以访问转发器模板以更新标记并重新编译它?

<div class="item-grid" ng-controller="ItemGridCtrl" ng-cloak item-grid>

    <h2>Item Grid</h2>

    <div class="item-grid__item-details">
        <div class="item-grid__item0">

            <button add-item="{12345}">ADD</button>

        </div>            
        <div class="item-grid__item1"> ... </div>
        <div class="item-grid__item2"> ... </div>
    </div>

    <div class="item-grid__modal" item-grid-modal>
        <h3>Want to add another item?</h3>
        <div related-items ng-repeat="item in relatedItems">
            <div class="item-grid__related-item" data-related-item-info>
                <span class="item-grid__heading">{{item.title}}</span>
                <span class="item-grid__label">TEXT TO CHANGE</span>
                <button class="item-grid__btn" related-item="{{item.id}}">ADD+</button>
            </div>
        </div>
    </div>

</div>


(function (modules) {

    //register this module to be injected into the main app as a dependency.
    modules.push("FooApp.itemGrid");

    //define "Product Grid" module
    var app = angular.module("FooApp.itemGrid", []);

    app.controller('ItemGridCtrl', ['$scope', '$rootScope',
    function ($scope, $rootScope) {

        //does controller stuff

    }]);

    app.directive('addItem', ['FooService', '$rootScope', '$timeout',
    function(FooService, $rootScope, $timeout) {
        return {
            restrict: 'A',
            scope: false,
            link: function($scope, el, attrs) {

                el.bind('click', function(e) {

                    //http post to add item to session
                    FooService.addItem({$scope.getJsonData(), function(response){

                        //post successful... pop up modal to show related items

                        $scope.relatedItems = $scope.filterSomeData();

                        if ($scope.relatedItems.length > 0) {
                            $scope.modal.show(); //popup the modal
                            $scope.modal.find('[ng-repeat] [data-related-item-info]').each(function() {
                                window.foo.angular.components.attachComponents(this);
                            });
                        }

                    });
                    }
                });
            }
        };
    }]);


    app.directive('itemGridModal', ['$rootScope', function($rootScope) {
        return {
            restrict: 'A',
            scope: false,
            link: function($scope, el, attrs) {
                $scope.modal = el.find('[modal]'); //adds modal element to controller scope
            }
        };
    }]);

})(window.foo.angularModules);

1 个答案:

答案 0 :(得分:1)

要更改模板,您可能需要访问该角度应用程序的$ templateCache服务。不是任何种类的范围。 https://docs.angularjs.org/api/ng/service/ $ templateCache

不确定是否可以这样做,但如果可以的话,祝你好运,因为那样会很酷。

另一种解决方案是使用MutationObserver(本机浏览器类)来监听DOM更改并运行自己的代码以在角度完成后检查/更新视图。这对于修改$ templateCache来说是一个更重的解决方案,但它绝对可以工作。

var mutationObserver = new MutationObserver(_.debounce(handleDomChanges, 25));
mutationObserver.observe(element, {childList: true, subtree: true, attributes: false});

注意:_.debounce函数是一个lo-dash库方法,可以防止此回调每秒运行太多次。