【问题标题】:The attributes passed to directive in AngularJS change only into directive scope but not outside在 AngularJS 中传递给指令的属性仅更改为指令范围而不是外部
【发布时间】:2013-05-17 13:44:36
【问题描述】:

我想使用指令来自定义我的代码。

我创建了一个按钮来切换控制器中定义的isCollapsedUpload 标志为:@scope.isCollapsedUpload=false

当用户按下按钮时,isCollapsedUpload 变为 true 或反之亦然,并且图标发生变化。

从控制器:

$scope.switcher = function (booleanExpr, trueValue, falseValue) {
    return booleanExpr ? trueValue : falseValue;  
}

$scope.isCollapsedUpload = false;  

<button class="btn" ng-click="isCollapsedUpload = !isCollapsedUpload">                
    <span>Upload file</span>
    <i class="{{ switcher( isCollapsedUpload, 'icon-chevron-right', 'icon-chevron-down' )}}"></i>
</button>

我写了这个directive

feederliteModule.directive('collapseExtend', function() {
return {
    restrict: 'E',
    scope: { isCollapsed:'@collapseTarget' },
    compile: function(element, attrs)
    { 
        var htmlText =
        '<button class="btn" ng-click="isCollapsed = !isCollapsed">'+       
        '       <span>'+attrs.label+'</span>'+  
        '       <i class="{{ switcher(isCollapsed, \'icon-chevron-right\', \'icon-chevron-down\' )}}"></i>'+  
        '</button>';

        element.replaceWith(htmlText);
    }
  }
});

现在我可以像这样使用它了:

<collapse-extend 
              collapse-target="isCollapsedUpload"
              label="Upload file"                  
></collapse-extend>

它不起作用。没有图标变化。没有错误,

isCollapsedUpload 标志不会改变。它只会变成 directive

我错过了什么吗?

【问题讨论】:

    标签: javascript angularjs angularjs-directive


    【解决方案1】:

    类没有正确更改的原因是因为您没有正确链接模板。如果您使用内置功能,这很容易解决:

    var feederliteModule = angular.module('feederliteModule', []);
    feederliteModule.directive('collapseExtend', [function() {
      return {
        restrict: 'E',
        scope: { 
          isCollapsed:'=collapseTarget',
          label: '@'
        },
        template: '<button class="btn" ng-click="isCollapsed = !isCollapsed">'+       
                    '<span>{{ label }}</span>'+  
                    '<i ng-class="{ \'icon-chevron-right\': isCollapsed, \'icon-chevron-down\': !isCollapsed }"></i>'+  
                  '</button>'
      }
    }]);
    feederliteModule.controller('test', ['$scope', function($scope) {
      $scope.isCollapsedUpload = false;
    }]);
    

    据我所知,通过替换父元素,您移除了与该对象绑定的隔离范围,而没有在按钮本身上创建新范围。

    【讨论】:

    • 我有 7 个相同类型的按钮,我想让我的代码更短
    • 所以想法是你想创建一个按钮,当你点击它时,它会改变按钮的类?
    • 它应该做很多事情,但首先我试着让它只改变标志
    • isCollapsed:'@collapseTarget' 应该是 isCollapsed:'=collapseTarget' 以获得预期的行为
    • @NickLarsen 'test' 在控制器中是什么意思?
    【解决方案2】:

    编辑: See a complete working fiddle with multiple buttons


    我建议使用service 而不是controller 来维护您的模型数据。当您的应用变得越来越复杂时,这可以让您更好地分离关注点:

    var feederliteModule = angular.module('feederliteModule', []);
    
    feederliteModule.service('btnService', function(){
        this.isCollapsedUpload = false;
        this.isCollapsedSomething = false;
    });
    
    feederliteModule.controller('btnController', function($scope, btnService){
        $scope.isCollapsedUpload = btnService.isCollapsedUpload;
        $scope.isCollapsedSomething = btnService.isCollapsedSomething;
    });
    
    feederliteModule.directive('collapseExtend', function() {
        return {
            restrict: 'E',
            scope: {
                isCollapsed:'=collapseTarget',
                label:'@'
            },
            replace: true,
            link: function (scope, element, attrs){
                scope.switcher = function (booleanExpr, trueValue, falseValue) {
                    return booleanExpr ? trueValue : falseValue;  
                };
                scope.toggleCollapse = function() {
                   scope.isCollapsed = !scope.isCollapsed;
                }              
            },
            template: '<button class="btn" ng-click="toggleCollapse()">'+       
            '<span>{{label}}</span>'+
            '<i ng-class="switcher(isCollapsed, \'icon-chevron-right\', \'icon-chevron-down\')"></i>'+  
            '</button>'
        }
    });
    

    另外,请注意您必须使用“=”而不是“@”,以使 isCollapsed 按预期工作。上面的答案也需要这个。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-04-07
      • 1970-01-01
      • 2014-07-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-04-20
      • 2014-05-18
      相关资源
      最近更新 更多