ng-show没有按预期绑定

时间:2014-09-29 13:10:40

标签: javascript angularjs

我试图进行一次简单的“切换”操作。在我的表格上。如果我单击一个按钮,那么我应该激活一个相应命名的部分,否则它应该从视图中隐藏。我的问题似乎是范围之一。如果我在子步骤中不使用隔离范围,那么两个子步骤将在一个切换上显示为活动而在另一个切换上显示为非活动(这是不正确的行为)。如果我使用隔离范围,则永远不会调用isActive()

我的代码如下。

<div ng-controller='SubstepCtrl'>
    <button activates='CreateNewMeter'>
        Create new Meter
    </button>

    <button activates='UseExistingMeter'>
        Use Existing Meter
    </button>

    <div class='sub-step' substep='CreateNewMeter' ng-show='isActive(name)'>
        <h1>Create New Meter</h1>
    </div>

    <div class='sub-step' substep='UseExistingMeter' ng-show='isActive(name)'>
        <h1>Use Existing Meter</h1>
    </div>
</div>

角:

.controller('SubstepCtrl', function($scope) {
    $scope.activeSubstepName = undefined;
    $scope.isActive = function(name) {
        return $scope.activeSubstepName == name;
    };
})

.directive('activates', function() {
    return {
        link: function($scope, $element, $attrs) {
            $element.on('click', function() {
                $scope.activeSubstepName = $attrs.activates;
                $scope.$apply();
            });
        }
    };
})

.directive('substep', function() {
    return {
        link: function($scope, $element, $attrs) {
            $scope.name = $attrs.substep;
        }
    };
});

我已经成功地使用JQuery以相当hacky的方式实现了这一点,但我想知道是否有一种方法可以使用Angular-ify。

预期的行为是,如果我点击&#34;创建新的仪表&#34;按钮,即&#34; CreateNewMeter&#34;应显示子步骤,并显示&#34; UseExistingMeter&#34;不应该。据我所知,这里的问题是子步骤div没有创建子范围并且都使用父范围 - 因此名称未定义 - 对吗?

如果是这样,我该如何解决这个问题?

2 个答案:

答案 0 :(得分:0)

试试这个,这可以避免创建自己的指令:

<div ng-controller='SubstepCtrl'>
    <button ng-click='setMeter("new")'>
        Create new Meter
    </button>

    <button activates='setMeter("existing")'>
        Use Existing Meter
    </button>

    <div class='sub-step' substep='CreateNewMeter' ng-show='meter === "new"'>
        <h1>Create New Meter</h1>
    </div>

    <div class='sub-step' substep='UseExistingMeter' ng-show='meter === "existing"'>
        <h1>Use Existing Meter</h1>
    </div>
</div>

在控制器范围内设置一个功能:

.controller('SubstepCtrl', function($scope) {
    $scope.activeSubstepName = undefined;
    $scope.isActive = function(name) {
        return $scope.activeSubstepName == name;
    };
    $scope.meter = null;
    $scope.setMeter = function(meterType) {
        $scope.meter = meterType;
    };
});

答案 1 :(得分:0)

这是一个解决方案,您可以使用它自己的隔离范围创建新指令。在我看来,这是一个更好的解决方案,特别是因为它允许您拥有任意数量的子步骤。

在指令中创建隔离范围时,您需要执行的操作具有nameisActive函数的属性。由于name只是您在html中定义的字符串,因此您可以将其指定为@属性,以便在指令范围内将其设置为您在html中指定的字符串。我创建了函数(使用&语法将其传递给指令),并且如果您注意到,为了传入您在函数中指定的参数showWhen在html中,您需要在指令中传递一个对象,该对象使用name作为键,并将指令name作为值。

html:

name

指令代码:

<div ng-controller='SubstepCtrl'>
    <button activates='CreateNewMeter'>
        Create new Meter
    </button>

    <button activates='UseExistingMeter'>
        Use Existing Meter
    </button>

    <button activates='UseImaginaryMeter'>
        Use Imaginary Meter
    </button>

    <button activates='none'>
        "Clear" all
    </button>

    <substep name="CreateNewMeter" show-when="isActive(name)">
      <h1>Create New Meter</h1>
    </substep>

    <substep name="UseExistingMeter" show-when="isActive(name)">
      <h1>Use Existing Meter</h1>
    </substep>

    <substep name="UseImaginaryMeter" show-when="isActive(name)">
      <h1>Use Imaginary Meter</h1>
    </substep>
</div>

以下是一个样本plunker:http://plnkr.co/edit/TKJehABKIPPHRbrUrqr3?p=preview