繁体   English   中英

在 AngularJS 中传递给指令的属性仅更改为指令范围,而不更改为指令范围之外

[英]The attributes passed to directive in AngularJS change only into directive scope but not outside

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

我创建了一个按钮来切换控制器中定义的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

我错过了什么?

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

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

据我所知,通过替换父元素,您正在删除此对象所关联的隔离范围,而无需在按钮本身上创建新的范围。

编辑:查看带有多个按钮的完整工作小提琴


我建议使用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按预期工作。 上面的答案也需要这个。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM