在Angular.js

时间:2015-08-11 19:30:16

标签: javascript angularjs

我继承了一些现有的Angular.js代码,我对此并不了解。我添加的一项功能是能够每五秒自动刷新视图中的数据。我通过更改init函数使用$interval函数调用自身来完成此操作:

model.init = function (token) {
    model.token = token;
    model.dataUrl = GlobScope.rootPath + "upload/checkdata/" + token;

    var loadData = function() {
        commonHelper.apiGet("api/bases/" + model.token, function(result) {
            model.bases = result.data.bases;
            model.files = result.data.files;
            model.messages = result.data.messages;
        });
    }

    // Reload data every 5 seconds
    $interval(function () {
        loadData();
    }.bind(this), 5000);

    loadData();
}

这很好用,现在随着服务器上的数据发生变化,它将在五秒钟内在客户端上更新。但是,有一个小问题。我的观点有很多标签:

<tabset>
   <tab heading="Input">
      <br />
      Some hard coded tab
   </tab>
   <tab ng-repeat="baseData in dataProcessingModel.bases" heading="{{baseData.base}}">
      Other tabs here depending on the data in the model
   </tab>
</tabset>

不幸的是,当刷新数据(每五秒钟)时,会再次选择第一个选项卡。

在数据继续刷新的同时,让当前选中的标签保持选中的最简单方法是什么?

我尝试过的一件事是将活动标签绑定到模型的某个部分,然后我可以在模型更改时再次设置它:

<tab ng-repeat="baseData in dataProcessingModel.bases" heading="{{baseData.base}}" active="dataProcessingModel.activeTab == baseData.base">

然后在loadData函数中:

var defaultTab ='输入';

var loadData = function() {
    commonHelper.apiGet("api/bases/" + model.token, function(result) {
        model.activeTab = defaultTab;
        model.bases = result.data.bases;
        model.files = result.data.files;
        model.messages = result.data.messages;
    });
}

接下来,每次选择新标签时,我都必须更改defaultTab。但是,使用此代码,标签会完全损坏。单击选项卡不会执行任何操作。

有一个简单的方法吗?我挖掘了tab docs并找不到任何有问题的东西。

3 个答案:

答案 0 :(得分:1)

问题在于ng-repeat如何跟踪项目。在您的情况下,每个“可重复”项目 - baseData - 都是一个对象,每次重新加载项目时它都是一个不同的对象,因此,ng-repeat无法知道哪个是哪个。因此,当您重新加载时,tab会创建全新的ng-repeat指令,因此active标签会丢失。

这是track by用于告诉ng-repeat如何跟踪对象的时间。似乎在你的情况下,$index跟踪是最合适的(如果你有一些其他的不可变属性来跟踪对象,你也可以使用它,例如baseData.id

<tabset>
  <tab ng-repeat="baseData in dataProcessingModel.bases track by $index"
       heading="{{baseData.base}}">
    {{baseData.content}}
  </tab>
</tabset>

<强> Demo

答案 1 :(得分:0)

var defaultTab = 'Input'; // set this tab to currentTab before you call loadData()

  $interval(function () {
        loadData(defaultTab);
    }.bind(this), 5000);

    loadData(defaultTab);

var loadData = function(defaultTab) {
    commonHelper.apiGet("api/bases/" + model.token, function(result) {
        model.activeTab = defaultTab;
        model.bases = result.data.bases;
        model.files = result.data.files;
        model.messages = result.data.messages;
    });

}

答案 2 :(得分:0)

如果您修改loadData()函数以接受可选参数,则可以触发组件有时滚动到您想要的位置,如果没有传入任何参数,则滚动到默认值。

var defaultTab = 0;
var loadData = function(activeTab = defaultTab) {
    commonHelper.apiGet("api/bases/" + model.token, function(result) {
        model.activeTab = activeTab;
        // scrollTo(activeTab)
        model.bases = result.data.bases;
        model.files = result.data.files;
        model.messages = result.data.messages;
    });
};