我的AngularJS应用程序的视图大量使用ng-repeat指令。它是这样完成的:
<div ng-repeat="branches in company">
<p>{{branches.name}}</p>
<p>{{branches.location}}</p>
<div>
<select ng-model="branches.officeInformationType">
<option ng-repeat="offices in branches">{{offices.type}}</option>
</select>
<select ng-model="branches.officeInformationMeters">
<option ng-repeat="offices in branches">{{offices.meters}}</option>
</select>
<select ng-model="branches.officeInformationColor">
<option ng-repeat="offices in branches">{{offices.color}}</option>
</select>
</div>
</div>
事实上,第二个ng-repeat和它之后的其他(分支中的办公室)实际上每次都是相同的,因此不需要为每个分支重新计算。它需要绑定到它所包含的行,以便以后保存它,所以branches.officeInformation模型仍然应该通过angular观察,但我想让整个程序更高效。
我正在使用angular-ui-router,当我改变我的“选择你的办公室”视图与其他任何视图之间的视图时,滞后是巨大的,几乎在离开“选择你的办公室”的等待时间的一分钟页。它呈现的速度足够快,整个渲染时间为2秒,但是当我离开页面时,需要花费大量时间才能切换到另一个视图。
任何想法,考虑到ng-model绑定“branches.officeInformation ..”是重要的?
编辑:我已经尝试删除嵌套的ng-repeats,并且对于我删除的每个ng-repeat,状态之间的转换越来越快。当我删除所有嵌套的ng-repeats时,转换变为瞬间,因此我认为它与ng-repeats有关。
ng-repeats由$ index跟踪,在可能的情况下,我使用::进行一次绑定。
感谢。
答案 0 :(得分:1)
我们可以在用户与之交互之前懒惰加载下拉列表选项。
首先,我们仅使用所选选项初始化每个下拉列表,以便在下拉列表关闭时看到它。
然后我们在每个下拉列表中附加ng-focus
指令。当我们的回调触发时,我们可以:
我不完全确定数据的结构(看起来某些数组上有其他属性)。所以我选择创建&#34;查看模型&#34;表示UI的对象。您可以根据自己的结构进行调整。
控制器:
// Set up some test office options (null for no selection)
var allOffices = [null];
for (var i = 0; i < 50; i++) {
allOffices.push(i);
}
// activeDropdown holds the dropdown that is currently populated with the full list
// of options. All other dropdowns are only populated with the selected option so
// that it shows when the dropdown is closed.
var activeDropdown;
$scope.company = [
// Branch 1
[
// These objects represent each dropdown
{
// Just the selected option until the user interacts with it
options: ["0"],
selected: "0"
}, {
// Just the selected option until the user interacts with it
options: ["1"],
selected: "1"
}, {
// Just the selected option until the user interacts with it
options: [null],
selected: null
}
],
// Branch 2
[
// These objects represent each dropdown
{
// Just the selected option until the user interacts with it
options: ["2"],
selected: "2"
}, {
// Just the selected option until the user interacts with it
options: ["3"],
selected: "3"
}, {
// Just the selected option until the user interacts with it
options: [null],
selected: null
}
]
];
// When the user interacts with a dropdown:
// - fully populate the array of options for that dropdown
// - remove all but the selected option from the previously active dropdown's
// options so that it still shows when the dropdown is closed
$scope.loadOffices = function (dropdown) {
if (activeDropdown === dropdown) {
return;
}
dropdown.options = allOffices;
if (activeDropdown) {
activeDropdown.options = [activeDropdown.selected];
}
activeDropdown = dropdown;
};
模板:
<div ng-repeat="branch in company">
<div ng-repeat="dropdown in branch">
Selected: {{ dropdown.selected }}
<select ng-focus="loadOffices(dropdown)" ng-model="dropdown.selected">
<option ng-repeat="o in dropdown.options">{{ o }}</option>
</select>
</div>
</div>
请注意,我测试时,ng-focus
是我需要应用于每个下拉列表的唯一指令。但是,您可能需要添加ng-keydown
,ng-mouseover
,ng-click
或其他内容,以使其在包括移动设备在内的所有方案中都能正常运行。
我也注意到了潜在的样式问题。当您专注于下拉列表时,我们会加载该下拉列表的所有选项。这可能会导致下拉列表的宽度发生变化,因此如果您可以为所有这些宽度设置相同的宽度,那么您应该是好的。
如果每个下拉列表中的选项数量很大,我们可以通过编写一些交互的自定义指令进一步优化,并允许共享实际的DOM元素选项。但我怀疑在这个例子中我们不得不走得那么远。
答案 1 :(得分:0)
您是否曾尝试过$ index&#39; ?它会减少有角度的手表开销。
类似的东西:
div ng-repeat="branches in company track by $index">
<p>{{branches.name}}</p>
<p>{{branches.location}}</p>
<div>
<select ng-model="branches.officeInformationType">
<option ng-repeat="offices in branches track by $index">{{offices.type}}</option>
</select>
<select ng-model="branches.officeInformationMeters">
<option ng-repeat="offices in branches track by $index">{{offices.meters}}</option>
</select>
<select ng-model="branches.officeInformationColor">
<option ng-repeat="offices in branches track by $index">{{offices.color}}</option>
</select>
</div>
</div>
答案 2 :(得分:0)
首先,感谢那些帮助我找到答案的人。
问题是我嵌套了太多的ng-repeats,每个重复元素都附加了太多的事件处理程序。 ng模型,ng-changes和ng-clicks真的很重,但元素的数量也失控了。
我通过使用单个选择而没有任何嵌套的ng-repeats解决了这个问题,这个选择(和选项)是一个模态视图,因此是一个不同的控制器。从该控制器返回选择结果,只有一个选择页面中的所有元素。当从模态返回数据时,我从视图的主控制器中使用它。
再次感谢。