简体   繁体   English

ng-show未按预期绑定

[英]ng-show not binding as expected

I'm trying to have a simple 'toggle' on my form. 我正在尝试在表单上进行简单的“切换”。 If I click one button, then I should activate a correspondingly-named section, otherwise it should be hidden from view. 如果单击一个按钮,则应激活相应命名的部分,否则应将其隐藏。 My issue appears to be that of a scope one. 我的问题似乎是范围一的问题。 If I don't use an isolated scope on my substeps, then both substeps will appear active on one toggle and inactive on the other (this is incorrect behaviour). 如果在子步骤中未使用隔离范围,则两个子步骤将在一个切换上显示为活动状态,而在另一个切换上显示为无效(这是错误的行为)。 If I do use an isolated scope, then isActive() is never called. 如果确实使用隔离范围,则永远不会调用isActive()

My code is as follows. 我的代码如下。

<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>

Angular: 角度:

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

I have managed to achieve this in a fairly hacky way with JQuery but I was wondering if there was a way to Angular-ify it. 我已经设法通过JQuery以一种相当古怪的方式实现了这一目标,但是我想知道是否有一种方法可以对它进行Angular化。

The expected behaviour is that if I click the "Create new Meter" button, that the "CreateNewMeter" substep should be displayed, and the "UseExistingMeter" should not. 预期的行为是,如果我单击“创建新仪表”按钮,则应显示“ CreateNewMeter”子步骤,而不应显示“ UseExistingMeter”。 As I understand the issue here is that the substep divs are not creating a subscope and are both using the parent scope - therefore name is undefined - right? 据我了解,这里的问题是子步骤div不会创建子范围,并且都在使用父作用域-因此名称未定义-对吗?

If so, how can I remedy this? 如果是这样,我该如何补救?

Try this, which avoids creating your own directive: 试试这个,避免创建自己的指令:

<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>

set a function on your controllers' scope: 在控制器的作用域上设置一个函数:

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

Here is a solution in which you create a new directive with it's own isolated scope. 这是一个解决方案,您可以使用其自己的隔离范围创建一个新指令。 In my opinion, this is a better solution, especially since it allows you to have as many sub-steps as you want. 我认为,这是一个更好的解决方案,尤其是因为它允许您根据需要包含任意多个子步骤。

What you need to do when you create your isolate scope in the directive is have a property for both the name and for the isActive function. 在伪指令中创建隔离范围时,需要做的是为nameisActive函数都具有一个属性。 Since the name is just a string that you have defined in your html, you can specify it as an @ attribute so that is set in your directives scope to the string you specify in your html. 由于name只是您在html中定义的字符串,因此您可以将其指定为@属性,以便在指令范围内将其设置为在html中指定的字符串。 I created the function (passing it to the directive using the & syntax) to be called showWhen and if you notice, in order to pass in the parameter name that you specify in your function in the html, you need to pass an object within your directive that uses name as a key with the directives name as the value. 我创建了名为showWhen的函数(使用&语法将其传递到指令),并且如果您注意到,为了传递在html中的函数中指定的参数name ,则需要name为键,以name为值的指令。

The html: 的HTML:

<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>

The directive code: 指令代码:

.directive('substep', function() {
    return {
      restrict: 'E',
      scope: {
        name: '@',
        showWhen: '&'
      },
      transclude: true,
      template: '<div ng-transclude class="sub-step" ng-show="showWhen({name:name})"></div>'
    };
});

Here is a sample plunker: http://plnkr.co/edit/TKJehABKIPPHRbrUrqr3?p=preview 这是一个示例插件: http ://plnkr.co/edit/TKJehABKIPPHRbrUrqr3?p=preview

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

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