ng-click in指令似乎只触发一次

时间:2019-06-19 13:55:40

标签: javascript angularjs angularjs-ng-click

我正在尝试实现一个指令,该指令将ng-click替换为。 ng-click调用一个函数,该函数将div的内容(始终相同)替换为另一个元素的内容,该元素的ID作为参数传递。 我设法使其正常运行,但仅在第一次单击时有效。此后,页面被重新加载,这似乎是因为未触发ng-click而是(空)href属性被触发了。

html代码:

  <!-- language: lang-html -->
  <div id="uiMain" class="container">
    Go to <go target="block01">01</go>, <go target="block02">02</go> or <go target="block03">03</go>
  </div>
  <div id="block01" class="block">
    Go to <go target="block02">02</go> or <go target="block03">03</go>
  </div>
  <div id="block02" class="block">
    Go to <go target="block01">01</go> or <go target="block03">03</go>
  </div>
  <div id="block03" class="block">
    Go to <go target="block01">01</go> or <go target="block02">02</go>
  </div>

和我的指令:

.directive('go', function() {
    return {
        restrict: "E",
        scope: {
            target: "@"
        },
        transclude: true,
        template: '<a href="" ng-click="displayBlock(\'{target}\')"><ng-transclude></ng-transclude></a>',
        link: function (scope, element, attrs) {
            scope.displayBlock = function() {
                // Get the content of the target block
                var content = angular.element(document.querySelector("#"+attrs.target));
                // Get the main container
                var mainContainer = angular.element(document.querySelector("#uiMain"));
                // then replace the link with it
                if (content !== null) { 
                    //mainContainer.html($compile(content.innerHTML)($scope)); 
                    mainContainer.html(content.html()); 
                }
            };
        }
    };
});

我尝试将函数放回到控制器中,但是他的行为是相同的。 我还尝试使用$ compile或$ apply来确保作用域与粘贴的html内容保持最新:这不起作用,因为目标块中的指令已被编译。

这是我plnkr的全部代码。

我希望能够单击链接来回移动,但是目前有些东西可以阻止ng-click多次触发。


编辑: 感谢Mosh-Feu,我设法通过向所有目标元素添加ng-non-bindable并按如下方式更改我的指令来使其工作:

.directive('go', function($compile) {
return {
    restrict: "E",
    scope: true,
    transclude: true,
    template: '<a href="" ng-click="displayBlock(\'{target}\')"><ng-transclude></ng-transclude></a>',
    link: function (scope, element, attrs) {
        scope.displayBlock = function() {
            // Get the content of the target block
            var content = angular.element(document.querySelector("#"+attrs.target));
            // Get the main container
            var mainContainer = angular.element(document.querySelector("#uiMain"));
            // then replace the link with it
            if (content != null) { 
                mainContainer.html(content.html()); 
                $compile(mainContainer)(scope);
            };
        };
    }
};

});

但是Aditya Bhave解决方案更干净,因此我将使用它。谢谢很多人!

1 个答案:

答案 0 :(得分:0)

问题是,当我们将div的innerHTML替换为html()时,它不会将其编译为angularjs代码。正确的方法是使用ng-templates。

看看这个Plunkr-http://next.plnkr.co/edit/x0TiUkka5nJwqB8K

  1. 我最初使用ng-include属性设置为mainBlock.html模板的div。
  2. “单击时”事件正在更改父控制器的模板URL。

注意-如果我们将temmplateURL作为属性传递给指令,然后在onclick而不是使用scope。$ parent进行更改,我们可以拥有更简洁的代码。