传递给angularjs中的指令的属性仅更改为指令范围,但不会更改为外部

时间:2013-05-17 13:44:37

标签: angularjs angularjs-directive

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

我已按下按钮,负责将控制器中定义的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

我错过了什么吗?

2 个答案:

答案 0 :(得分:2)

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

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;
}]);

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

答案 1 :(得分:1)

编辑: 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按预期工作。上面的答案也需要这个。