阻止 DOM 重绘的对话框
Dialog preventing DOM from redrawing
我有一个内置页面 angular。该页面显示了一组已分页的数据。我有一个可以用搜索框搜索的页面。由于一些关于每个页面的组成的自定义规则,分页是手工构建的。但是构建分页是在 buildPages() 方法中设置的,从那里它是一个简单的调用来构建直接更新页面绘制范围的页面。
所以通常搜索是这样工作的:
输入搜索。
Watcher 在搜索时捕捉到变化。
Watcher 设置搜索变量
观察者调用 buildPages();
buildPages 重建分页并更新范围。
范围正在更新,分页和显示的数据已重绘。
现在一切正常。但我需要添加一个对话框来询问用户是否要更改搜索或保留搜索,并且此对话框有时仅根据特定条件出现。
我的问题是,如果我打开一个对话框并通过在对话框中单击按钮调用 buildPages(),它会正确更新范围,但不会重绘页面。
因此,例如,您有 50 页,并且显示第 1 页,共 50 页。然后您输入搜索。搜索过滤掉这 50 页中的 25 页,剩下 25 页。您最初所在的页面也会被过滤掉。如果没有对话框,在搜索中键入内容将导致您出现在第一个过滤页面的第 1/25 页。但是,从对话框触发搜索仍会显示在未过滤页面的第 1 页,即第 1/50 页。在分页控件上单击“下一步”将正确地将您带到第二个筛选页面 2/25,从那里单击返回将正确显示在筛选页面的第 1/25 页。
即使像触发悬停这样简单的操作也会导致页面正确重绘。
这是怎么回事?为什么对话框阻止重绘?
这是我在观察器中使用的代码(稍微简化)。
$scope.$watch('searchText', function(newVal, oldVal) {
currentSearch = newVal;
if(newVal !== oldVal){
if(displayFlag){
j$( "#dialog-confirm").dialog({
resizable: false,
width:450,
height:240,
modal: true,
buttons: {
"Search": function() {
j$( this ).dialog( "close" );
buildPages();
},
Cancel: function() {
j$( this ).dialog( "close" );
return false;
}
}});
}
else
{
buildPages();
}
}
});
我试过在搜索点击中包含 return true 或 false。我还尝试在搜索点击中切换对话框关闭和 buildPages 的顺序。
我不确定 j$()
是否是一个 angular 库。看来未必。
请记住 Angular 除了它自己之外不知道任何类型的事件或更改,因此,如果您正在使用 jQuery 或其他类似的库执行操作 .dialog
,执行调用后,您可能需要调用 $scope.$digest();
或 $scope.$apply()
来触发 angular 摘要循环。
scope.$digest()
只会触发当前作用域的观察者,scope.$apply
(推荐)会评估传递的函数,运行 $rootScope.$digest()
.
buttons: {
"Search":
function() {
j$( this ).dialog( "close" );
buildPages();
$scope.$apply(); //After function is executed a cycle will occur.
},
Cancel: function() {
j$( this ).dialog( "close" );
return false;
}
}
我认为您的情况可能不会更新视图,因为 angular 没有被告知执行摘要循环。
我有一个内置页面 angular。该页面显示了一组已分页的数据。我有一个可以用搜索框搜索的页面。由于一些关于每个页面的组成的自定义规则,分页是手工构建的。但是构建分页是在 buildPages() 方法中设置的,从那里它是一个简单的调用来构建直接更新页面绘制范围的页面。
所以通常搜索是这样工作的:
输入搜索。
Watcher 在搜索时捕捉到变化。
Watcher 设置搜索变量
观察者调用 buildPages();
buildPages 重建分页并更新范围。
范围正在更新,分页和显示的数据已重绘。
现在一切正常。但我需要添加一个对话框来询问用户是否要更改搜索或保留搜索,并且此对话框有时仅根据特定条件出现。
我的问题是,如果我打开一个对话框并通过在对话框中单击按钮调用 buildPages(),它会正确更新范围,但不会重绘页面。
因此,例如,您有 50 页,并且显示第 1 页,共 50 页。然后您输入搜索。搜索过滤掉这 50 页中的 25 页,剩下 25 页。您最初所在的页面也会被过滤掉。如果没有对话框,在搜索中键入内容将导致您出现在第一个过滤页面的第 1/25 页。但是,从对话框触发搜索仍会显示在未过滤页面的第 1 页,即第 1/50 页。在分页控件上单击“下一步”将正确地将您带到第二个筛选页面 2/25,从那里单击返回将正确显示在筛选页面的第 1/25 页。
即使像触发悬停这样简单的操作也会导致页面正确重绘。
这是怎么回事?为什么对话框阻止重绘?
这是我在观察器中使用的代码(稍微简化)。
$scope.$watch('searchText', function(newVal, oldVal) {
currentSearch = newVal;
if(newVal !== oldVal){
if(displayFlag){
j$( "#dialog-confirm").dialog({
resizable: false,
width:450,
height:240,
modal: true,
buttons: {
"Search": function() {
j$( this ).dialog( "close" );
buildPages();
},
Cancel: function() {
j$( this ).dialog( "close" );
return false;
}
}});
}
else
{
buildPages();
}
}
});
我试过在搜索点击中包含 return true 或 false。我还尝试在搜索点击中切换对话框关闭和 buildPages 的顺序。
我不确定 j$()
是否是一个 angular 库。看来未必。
请记住 Angular 除了它自己之外不知道任何类型的事件或更改,因此,如果您正在使用 jQuery 或其他类似的库执行操作 .dialog
,执行调用后,您可能需要调用 $scope.$digest();
或 $scope.$apply()
来触发 angular 摘要循环。
scope.$digest()
只会触发当前作用域的观察者,scope.$apply
(推荐)会评估传递的函数,运行 $rootScope.$digest()
.
buttons: {
"Search":
function() {
j$( this ).dialog( "close" );
buildPages();
$scope.$apply(); //After function is executed a cycle will occur.
},
Cancel: function() {
j$( this ).dialog( "close" );
return false;
}
}
我认为您的情况可能不会更新视图,因为 angular 没有被告知执行摘要循环。