【问题标题】:Directive Doesn't Update Angular指令不更新 Angular
【发布时间】:2015-06-01 12:42:54
【问题描述】:

Js:

myApp.directive('locationClass', function ($location) {

    return {
        restrict : 'A',
        link: function (scope, element) {
            var currentLocation = $location.path();

            var formatCurrentLocation = currentLocation.replace(/\//g, " ");

            //console.log(currentLocation);
            element.addClass(formatCurrentLocation);
    }

    }

});  

HTML

<html ng-app="myApp" ng-controller="headerCtrl as header" location-class>  

它可以正常工作,但是当页面加载时,它会更新,当我更改步骤时,值不会更新。

网址示例CounterForm/InstallCounterCounterForm/CounterEquipment

我正在使用Ui-router
任何的想法 ? 谢谢

【问题讨论】:

  • 什么时候更新?范围属性何时更改?

标签: angularjs angular-directive


【解决方案1】:

当指令被渲染时,你的链接函数只被调用一次。

这意味着当您的 html 第一次呈现时,只有调用该函数。所以它完成了工作。当url发生变化时,需要监听器根据变化进行更新。

它不会与 URL 建立实时连接。

您需要在链接函数中为 $locationChangeSuccess 事件创建一个监听器。那应该做你的工作。

查看here 以获取文档。在那里搜索此功能。 然后,每当您更改 url 时,都会调用它并完成更改。你的指令变成这样:

myApp.directive('locationClass', function ($location, $rootScope) {

    return {
        restrict : 'A',
        link: function (scope, element) {
            $rootScope.$on('$locationChangeSuccess', function () {
                var currentLocation = $location.path();

                var formatCurrentLocation = currentLocation.replace(/\//g, " ");

                //console.log(currentLocation);
                element.addClass(formatCurrentLocation);
            });

    }
}

为了切换类而更新:

您使用范围变量代替。我们可以只用一个变量来存储类并将变量放在 html 上。检查 html 中的 locationClass 变量。

所以你的 html 会是这样的:

<html ng-app="myApp" ng-controller="headerCtrl as header" location-class class="{{locationClass}}">  

和你的指令,我们修改为:

myApp.directive('locationClass', function ($location, $rootScope) {

    return {
        restrict : 'A',
        link: function (scope, element) {
            $rootScope.$on('$locationChangeSuccess', function () {
                var currentLocation = $location.path();

                var formatCurrentLocation = currentLocation.replace(/\//g, " ");
                scope.locationClass = formatCurrentLocation;

            });

    }
}

所以现在每当你改变你的位置,当改变成功时,变量将在类属性上更新,你的 html 将有新的类。您无需手动删除旧类。

我认为这将解决问题,也是一种更好的做事方式。除非在 AngularJS 中必要,否则我们不想直接处理 DOM。如果变量可以做到这一点,我们就做到了。

更新 2:(如果您想使用手表)

我们可以监视 location.path() 并使用它来跟踪类名。

myApp.directive('locationClass', function ($location, $rootScope) {

    return {
        restrict : 'A',
        link: function (scope, element) {

            scope.$watch('$location.path()', function(currentLocation) {

                var formatCurrentLocation = currentLocation.replace(/\//g, " ");
                scope.locationClass = formatCurrentLocation;
            });

    }
}

但我仍然建议您寻找位置更改成功的监听器。 原因是手表很重,并且每次范围变脏时都会触发(如果范围在主体上,则意味着几乎每次),而事件侦听器仅在 url 更改时才会调用该函数。您可以在函数中放置一个控制台来检查和验证这一点。

【讨论】:

  • 问题是,新的类不会被旧的替换,只需在html中添加类
  • 对其进行了修改。请检查。
  • 感谢您的有用提示,但课程无法正常工作,我也尝试了 ng-class
  • 它对我有用。问题是指令中没有定义 $scope。纠正那个。您一定也遇到了同样的错误。
  • 从范围中删除 $ 并再次检查
【解决方案2】:

你必须注意你的范围变量的变化

return {
   restrict: 'A',
   scope: {
     name: '='
   },
   link: function($scope) {
     $scope.$watch('name', function() {
        // all the code here...
     });
   }
};

根据你的例子,我认为它会起作用

 scope.$watch('data', function(){ // replace data with variable on which you have to watch change
                var currentLocation = $location.path();
                var formatCurrentLocation = currentLocation.replace(/\//g, " ");
                element.addClass(formatCurrentLocation);
                $compile(element.contents())(scope);

            });

【讨论】:

  • 1+ 谢谢,那是什么? $compile(element.contents())(scope);
  • 您可以使用 compile 将作用域和模板链接在一起。如果您的模板或 html 中存在任何变量,那么我们可以使用 compile 链接该变量的范围
  • 编译是遍历 DOM 树并将 DOM 元素与指令匹配的过程。 docs.angularjs.org/api/ng/service/$compile
  • 还有一个问题,我如何使用您的 $watch 中的数据?
  • 手表是正确的,但@keval,你不能继续编译整个指令。如果它是某个小元素级别的指令,则完全有道理,但是当您在每次位置更改时继续编译整个主体(请参阅指令位置)时,不建议这样做。为什么?因为,它基本上会重新渲染所有静态的、与位置变化无关的元素,并使应用程序变得过于繁重。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-01-01
  • 1970-01-01
  • 2020-03-03
相关资源
最近更新 更多