【问题标题】:run angular compile only when a certian section of a page has changed仅当页面的某个部分发生更改时才运行角度编译
【发布时间】:2015-03-13 06:44:39
【问题描述】:

所以我正在开发一个应用程序,该应用程序有许多通过 jquery ajax 加载的部分,一些在它启动时,一些在响应其他部分,有些甚至是嵌套的。我不能做的是说“哦,mainContainer 中的内容改变了?”好吧,去编译那部分的代码。

原因是我希望能够将ui-sref's 放入我们不想弄乱的部分代码中。我想出了一个解决方案,但它并没有像我想象的那样工作,我在自定义指令中添加了$watch,但它触发了无数次。这是代码。

希望有人可以解释如何仅在 X <div> 中的内容通过发生的许多 ajax 调用之一更改时才运行一次,这样我就不需要立即将所有旧的将代码转换为 angular,并可以链接到使用 angular 的新代码。

app.directive('ngMainContainer', function ($compile, $timeout) {
    console.log("main container directive");
    return function (scope, elem, attrs) {
        scope.$watch(function () {
            return elem;
        }, function (val) {
            console.log("Something changed. " + val);
            $timeout(function () {
                $compile(val)(scope);
            }, 0);
        });
    };
});

再次,我认为对传递给指令的元素进行监视是答案,但是即使我移动鼠标并单击通过 jquery ajax 加载的容器外部某处的页面,它也会运行。

【问题讨论】:

  • 您是否尝试过将作用域变量设置为elem.html() 并在其上设置$watch
  • 我收到此错误“错误:[jqLit​​e:nosel] jqLit​​e 不支持通过选择器查找元素!请参阅:docs.angularjs.org/api/angular.elementerrors.angularjs.org/1.3.5/jqLite/nosel - 这看起来应该不难,显然我错过了一些东西。
  • 请看我的回答和我回答的下编辑部分。我试图解决两种方法来解决这个问题,其中一种包括不依赖于“注入”方面的角度的代码

标签: javascript jquery html ajax angularjs


【解决方案1】:

这是一个可能对您有用的解决方案。我将指令 ngMainContainer 放在我们想要观察其 html 内容的元素上。

在我们的控制器中,我添加<p>{{ content }}</p>,我首先添加$compile,然后更新范围var,如$scope.html = angular.element(myDiv).html()。这是我们的指令$watch 触发的地方。

这是完整的工作示例。 <button> 正在附加 html,但这应该模拟 ajax 调用请求的解析完成。

JSFiddle Link

app.directive('ngMainContainer', [function () {
    return {
        restrict: 'A',
        link: function (scope, elem, attrs) {

            scope.$watch('html', function(n, o) {
                if(n !== o) {
                    console.log(elem.contents())
                    // html has changed, do something!
                }
            });
        }
    }
}]);


app.controller('ctrl', ['$scope', '$compile', function($scope, $compile) {

    $scope.content = "scope content";

    var myDiv = document.getElementById('main');

    $scope.appendContent = function() { // Replicate Ajax Callback

        var dynamic = $compile('<p ng-cloak>{{ content }}</p>')($scope); // Compile content        
        angular.element(myDiv).append(dynamic);
        $scope.html = angular.element(myDiv).html()
    }
}]);

编辑

这是一种在将内容附加到 &lt;div&gt; 时执行此操作的方法,在执行附加的代码上没有角度的概念

Updated JSFiddle

<button id="noAngular" onclick="noAngularAppend()">Append Content - No Angular</button>


function noAngularAppend() {
    angular.element(document.getElementById('main')).scope().externallyAppend('<p ng-cloak>{{ content }}</p>');
}


指令函数(注入$compile

scope.externallyAppend = function(element) {
    var node = $compile(element)(scope);
    elem.append(node);
    scope.$apply(scope.html = elem.contents());
}

【讨论】:

    【解决方案2】:

    Sal,我对你的答案投了赞成票,因为它最终确实帮助我解决了这个问题,但最终这并不是我想要的。

    这就是我最终的结果。在主应用程序的控制器中,有一个函数,其中只有两行。

     $scope.doReshing = function (element) {
        $compile(angular.element(element))($scope);
        $scope.$apply();
    }
    

    然后,在 document.ready() 顶部包含 ng 指令的任何部分中,我放置了以下内容。

     var removeableContentContainer = $('#removableContentContainer');
     angular.element(removeableContentContainer).scope().doReshing(removeableContentContainer);
    

    这正是我想要的。它让我对现有应用程序的工作方式几乎没有任何改变,让我在“旧”代码中添加 ui-srefs,而不必担心它如何或何时加载、何时加载、document.ready()触发,它会告诉 Angular 它需要编译。这是我的目标,您可以在任何时间点提取一些代码,并让它们本质上就像它们是带有控制器的页面的一部分一样。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-08-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-03-05
      • 1970-01-01
      相关资源
      最近更新 更多