2014-09-29 77 views
0

我试图在窗体上添加一个简单的“切换”。如果我点击一个按钮,那么我应该激活一个相应命名的部分,否则应该隐藏视图。我的问题似乎是范围之一。如果我没有在子步骤中使用隔离范围,那么这两个子步骤在一个切换点上将显示为激活状态,而在另一个子切换点上处于非激活状态(这是不正确的行为)。如果我使用一个孤立的范围,然后isActive()永远不会被调用。ng-show没有按预期方式绑定

我的代码如下。

<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相当哈克的方式来实现这一点,但我不知道是否有一种方式来角IFY它。

预期的行为是,如果我点击“创建新仪表”按钮,应该显示“CreateNewMeter”子步骤,并且“UseExistingMeter”不应该显示。据我了解这里的问题是子步骤div不创建一个子范围,都使用父范围 - 因此名称是未定义的 - 对吗?

如果是这样,我该如何补救?

+0

对不起,是的,我跳过了这一点。但是它在实际代码中是$ scope.activeSubstepName。 – 2014-09-29 13:23:14

+0

您的子步骤指令将控制器中的$ scope.name设置为页面上最后一个子步骤元素的名称,这就是为什么您看到它们都显示出来(它们都使用相同的“标志”) – JoseM 2014-09-29 13:26:25

+0

您需要传递名称妥善.. http://plnkr.co/edit/2KowNF?p =预览You'r子步骤只使用控制器范围,因此范围中的name属性将被指令的最后一个实例覆盖。 – PSL 2014-09-29 13:27:43

回答

0

这里是您创建一个新的指令与它的一个解决方案拥有孤立的范围。在我看来,这是一个更好的解决方案,尤其是因为它可以让你拥有尽可能多的子步骤。

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

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

该指令代码:

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

这里是一个示例plunker:http://plnkr.co/edit/TKJehABKIPPHRbrUrqr3?p=preview

+0

你能解释一下'&'做什么? :)我知道我可以谷歌它,但我为了完整起见,以防其他人在这个问题上绊倒。 – 2014-09-29 14:22:16

+0

当你想传递一个指向该指令的指针以便能够从你的控制器作用域调用一个函数时,你可以在隔离作用域定义对象中使用'&'。请参阅[指令范围文档](https://docs.angularjs.org/api/ng/service/$compile#-scope-)以获取更多信息 – JoseM 2014-09-29 14:31:25

+0

将此标记标记为已接受,因为它不受2个选项的限制。如果这是一个人造pais我道歉:( – 2014-09-29 14:33:23

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; 
    }; 
}); 
+0

这是一个体面的解决方案,但是如果我有多个子步骤,它会中断。这就是说我的问题只允许两个子步骤,所以我想它会这样做:p – 2014-09-29 13:56:42

+0

请参阅问题更新 – Fordio 2014-09-29 14:00:44

+0

谢谢男人 - 这是完美的。:) – 2014-09-29 14:00:52

相关问题