md-tabs:从ui路由器内部调用函数时,针对md-selected的设置变量不起作用 [英] md-tabs: setting variable for md-selected not working when calling function from inside ui-router

查看:79
本文介绍了md-tabs:从ui路由器内部调用函数时,针对md-selected的设置变量不起作用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个ui-router模板,其中包含md-tabs,其中有些选项卡是静态的,而另一些选项卡是使用ng-repeat遍历给定数据模型数组动态创建的.

I have a ui-router template containing md-tabs from which some tabs are static, others are created dynamically using ng-repeat iterating through a given array of the data model.

在这些动态创建的标签中,有三个按钮可以执行以下操作

Inside those dynamically created tabs there are three buttons to do the following

  • 将标签向左移动一个位置
  • 将标签向右移动一个位置

move tab按钮在同一控制器内调用一个功能.当前显示的选项卡的$index值以及所需的方向(向左移动-1,向右移动1)都将传递给该函数.

The move tab buttons call a function inside the same controller. The $index value of the currently shown tabs as well as the desired direction (-1 for moving left, 1 for moving right) are passed to the function.

因此,该视图的HTML代码段如下所示:

So the HTML-snippet for the view looks as follows:

<md-content flex layout-padding>
    <md-card>
        <md-tabs md-dynamic-height md-border-bottom md-autoselect md-swipe-content md-selected="selectedTab">
            <md-tab id="{{ 'tab' + $index }}" data-ng-repeat="tab in tabs track by $index">
                <md-tab-label>Tab {{ $index + 1 }}</md-tab-label>
                <md-tab-body>
                    <md-card-title>
                        <md-card-title-text>
                            <div flex layout="row">
                                <div flex><span class="md-headline">Tab {{ $index + 1 }}</span></div>
                                <div flex align="right">
                                    <md-button ng-click="moveTab(-1, $index)">Move tab left</md-button>
                                    <md-button ng-click="moveTab(1, $index)">Move tab right</md-button>
                                </div>
                            </div>
                        </md-card-title-text>
                    </md-card-title>
                    <md-card-content>
                    <p>This is tab {{ $index + 1 }}</p>
                    </md-card-content>
                </md-tab-body>
            </md-tab>
        </md-tabs>
    </md-card>
</md-content>

MainController中以如下方式实现了移动选项卡的功能:

The function moving the tabs is implemented in MainController as:

$scope.moveTab = function(direction, TabIdx) {
    var staticTabs = 3

    var arr = $scope.tabs
    var fromIdx = sectorIdx
    var toIdx = tabIdx + direction

    // correct `toIdx` in order to prevent index overflow for first/last array element
    if (toIdx < 0) {
        toIdx = arr.length - 1
    } else if (toIdx > arr.length-1) {
        toIdx = 0
    }
    else {
        ; // nothing to do here since `toIdx` does not need to be corrected
    }

    var tab = arr.splice(fromIdx, 1)[0]
    arr.splice(toIdx, 0, tab)

    $scope.selectedTab = staticTabs + toIdx
    console.log($scope.selectedTab)
}    

单击所需按钮以移动选项卡后,将根据需要显示相应选项卡附近的数据. 这表明操作$scope.tabs数组可以正常工作.另外,日志消息显示,即使$scope.selectedTab的新值也可以正确计算. 但是,视图中没有选择新标签.

After clicking the desired button to move a tab, the data of the according tab neigbour is displayed as desired. This shows that maniupulating the $scope.tabs array works correctly. Additionally the log-message shows that even the new value for $scope.selectedTab is calculated correctly. However, the new tab is not selected in the view.

这使我感到困惑,因此变量$scope.tabs$scope.selectedTab都在同一控制器中定义,并且应属于同一$scope实例的一部分. 此外,操纵的$scope.tabs数组在其他视图中使用,并以新的顺序显示选项卡数据,而$scope.selectedTab的新值似乎不可用,并且显示的选项卡未更改.

This confuses me hence both variables $scope.tabs and $scope.selectedTab are defined in the same controller and should be part of the same $scope instance. In addition, the manipulated $scope.tabs array is used in other views and shows the tab data in the new order, whereas the new value for $scope.selectedTab does not seem to be available and the shown tab does not change.

推荐答案

这是范围继承的问题,因为在继承父范围时,使用除对象以外的其他数据类型的数据绑定没有双向绑定.

This was a problem of scope inheritance since data-bindings using other datatypes than objects do not have two-way-binding when inheriting the parent scope.

查看文档:

范围继承通常很简单,而您通常不知道 甚至需要知道它正在发生...直到尝试2向数据绑定 (例如表单元素,ng-model)转换成原始图元(例如数字,字串, 布尔值)从子作用域内部在父作用域上定义.它 不能像大多数人期望的那样工作.怎么了 是子作用域获得自己的属性来隐藏/阴影 具有相同名称的父属性.这不是AngularJS的东西 这样做–这就是JavaScript原型继承的工作方式.新的 AngularJS开发人员通常不会意识到ng-repeat,ng-switch, ng-view和ng-include都会创建新的子范围,所以问题就出在 当涉及到这些指令时,通常会显示出来. [...]

Scope inheritance is normally straightforward, and you often don't even need to know it is happening... until you try 2-way data binding (i.e., form elements, ng-model) to a primitive (e.g., number, string, boolean) defined on the parent scope from inside the child scope. It doesn't work the way most people expect it should work. What happens is that the child scope gets its own property that hides/shadows the parent property of the same name. This is not something AngularJS is doing – this is how JavaScript prototypal inheritance works. New AngularJS developers often do not realize that ng-repeat, ng-switch, ng-view and ng-include all create new child scopes, so the problem often shows up when these directives are involved. [...]

通过遵循 最佳实践"总是有一个."在您的ng模型中[...]

This issue with primitives can be easily avoided by following the "best practice" of always have a '.' in your ng-models [...]

更改后

selectedTab

selectedTab.inputTab

在给定的HTML代码段和JS代码段中,一切都按预期工作.

in both the given HTML- and JS-snippets everything works as expected.

这篇关于md-tabs:从ui路由器内部调用函数时,针对md-selected的设置变量不起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆