angular 指令的内容未呈现,除非您手动强制页面重排
angular directive's content not rendered, unless you force page reflow manually
我在 ui-bootstrap 和 angular 1.4 中遇到以下奇怪行为。当我将 footable
table 指令放入名为 hpanel 的自定义 bootstrap 面板时,footable
最初比面板本身占据更多位置:
但是如果我调整屏幕大小(例如,通过折叠此处的开发人员工具面板),footable
指令会自行绘制并适合面板:
重要的是,我在使用 angular-c3
图表指令时遇到过类似的问题(它们加载不正确,超出了 hpanel 的大小,但在调整页面大小时表现良好),所以它可能不仅仅是一个损坏的指令。
你见过类似的东西吗?
详情:
下面是一个 HTML 模板,表示页面的非功能部分。我们有一个 hpanel
并且在其中应用了 table 和 angular-footable directive ^1.0.3。
这是模板 (toolList.html
):
<div class="content">
<div class="row">
<div class="col-lg-12">
<div class="hpanel">
<div class="panel-heading">
<div class="panel-tools">
<a class="showhide"><i class="fa fa-chevron-up"></i></a>
<a class="closebox"><i class="fa fa-times"></i></a>
</div>
Available tools.
</div>
<div class="panel-body">
<input type="text" class="form-control input-sm m-b-md" id="filter" placeholder="Search in table">
<table id="example1" class="footable table table-stripped toggle-arrow-tiny" data-page-size="8" data-filter=#filter>
<thead>
<tr>
<th data-toggle="true">Id</th>
<th>Class</th>
<th>Label</th>
<th>Description</th>
<th data-hide="all">Owner</th>
<th data-hide="all">Contributor</th>
<th data-hide="all">Inputs</th>
<th data-hide="all">Outputs</th>
<th data-hide="all">Base command</th>
<th data-hide="all">Arguments</th>
<th data-hide="all">Requirements</th>
<th data-hide="all">Hints</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="tool in vm.tools">
<td><a ui-sref="tool-detail({id: tool.id})">{{tool.id}}</a></td>
<td>{{tool.tool_class}}</td>
<td>{{tool.label}}</td>
<td>{{tool.description}}</td>
<td>{{tool.owner}}</td>
<td>{{tool.contributor}}</td>
<td>{{tool.baseCommand}}</td>
<td>{{tool.arguments}}</td>
<td>{{tool.requirements}}</td>
<td>{{tool.hints}}</td>
</tr>
</tbody>
<tfoot>
<tr>
<td colspan="5">
<ul class="pagination pull-right"></ul>
</td>
</tr>
</tfoot>
</table>
</div>
</div>
</div>
</div>
</div>
footable 指令用于隐藏 table 的某些列并在单击 table 行时显示它们。它还提供分页。它似乎在页面加载时不起作用,但是当我调整页面大小时并且屏幕大小超过媒体类型边距(因此从中等大小的屏幕变成大屏幕 bootstrap css 条款),分页按钮出现,隐藏的列被隐藏。
以下是我在主模块中导入 footable
指令的方法 app.js
:
require("footable/js/footable");
require("footable/js/footable.filter");
require("footable/js/footable.striping");
require("footable/js/footable.sort");
require("footable/js/footable.paginate");
require("footable/css/footable.core.css")
require("angular-footable");
angular.module("app", [
...,
"ui.footable",
])
我使用 webpack
加载所有这些模块,并使用 bower
安装依赖项。
hpanel 只是一个 scss
class,这里是它的定义:
/* Panels */
.hpanel > .panel-heading {
color: inherit;
font-weight: 600;
padding: 10px 4px;
transition: all .3s;
border: 1px solid transparent;
}
.hpanel .hbuilt.panel-heading {
border-bottom: none;
}
.hpanel > .panel-footer, .hpanel > .panel-section {
color: inherit;
border: 1px solid $border-color;
border-top: none;
font-size: 90%;
background: $color-bright;
padding: 10px 15px;
}
.hpanel.panel-collapse > .panel-heading, .hpanel .hbuilt {
background: #fff;
border-color: $border-color;
border: 1px solid $border-color;
padding: 10px 10px;
border-radius: 2px;
}
.hpanel .panel-body {
background: #fff;
border: 1px solid $border-color;
border-radius: 2px;
padding: 20px;
position: relative;
}
.hpanel.panel-group .panel-body:first-child {
border-top: 1px solid $border-color;
}
.hpanel.panel-group .panel-body {
border-top: none;
}
.panel-collapse .panel-body {
border: none;
}
.hpanel {
background-color: none;
border: none;
box-shadow: none;
margin-bottom: 25px;
}
.panel-tools {
display: inline-block;
float: right;
margin-top: 0;
padding: 0;
position: relative;
}
.hpanel .alert {
margin-bottom: 0;
border-radius: 0;
border: 1px solid $border-color;
border-bottom: none;
}
.panel-tools a {
margin-left: 5px;
color: lighten($color-text, 20%);
cursor: pointer;
}
.hpanel.hgreen .panel-body {
border-top: 2px solid $color-green;
}
.hpanel.hblue .panel-body {
border-top: 2px solid $color-blue;
}
.hpanel.hyellow .panel-body {
border-top: 2px solid $color-yellow;
}
.hpanel.hviolet .panel-body {
border-top: 2px solid $color-violet;
}
.hpanel.horange .panel-body {
border-top: 2px solid $color-orange;
}
.hpanel.hred .panel-body {
border-top: 2px solid $color-red;
}
.hpanel.hreddeep .panel-body {
border-top: 2px solid $color-red-deep;
}
.hpanel.hnavyblue .panel-body {
border-top: 2px solid $color-navy-blue;
}
.hpanel.hbggreen .panel-body {
background: $color-green;
color: #fff;
border:none;
}
.hpanel.hbgblue .panel-body {
background: $color-blue;
color: #fff;
border:none;
}
.hpanel.hbgyellow .panel-body {
background: $color-yellow;
color: #fff;
border:none;
}
.hpanel.hbgviolet .panel-body {
background: $color-violet;
color: #fff;
border:none;
}
.hpanel.hbgorange .panel-body {
background: $color-orange;
color: #fff;
border:none;
}
.hpanel.hbgred .panel-body {
background: $color-red;
color: #fff;
border:none;
}
.hpanel.hbgreddeep .panel-body {
background: $color-red-deep;
color: #fff;
border:none;
}
.hpanel.hbgnavyblue .panel-body {
background: $color-navy-blue;
color: #fff;
border:none;
}
.panel-group .panel-heading {
background-color: $color-bright;
}
.small-header .hpanel {
margin-bottom: 0;
}
.small-header {
padding: 0 !important;
}
.small-header .panel-body {
padding: 15px 25px;
border-right: none;
border-left: none;
border-top: none;
border-radius: 0;
// background: $color-bright;
}
.panel-body h5, .panel-body h4 {
font-weight: 600;
}
.small-header .panel-body h2 {
font-size: 14px;
font-weight: 600;
text-transform: uppercase;
margin: 0 0 0 0;
}
.small-header .panel-body small {
color: lighten($color-text, 10%);
}
.hbreadcrumb {
padding: 2px 0px;
margin-top: 6px;
margin-bottom: 0px;
list-style: none;
background-color: #fff;
font-size: 11px;
> li {
display: inline-block;
+ li:before {
padding: 0 5px;
color: $color-navy-blue;
}
}
> .active {
color: lighten($color-text,20%);
}
}
.wrapper {
padding: 10px 20px;
}
.hpanel.collapsed .panel-body, .hpanel.collapsed .panel-footer {
display: none;
}
.hpanel.collapsed .fa.fa-chevron-up:before {
content: "\f078";
}
.hpanel.collapsed .fa.fa-chevron-down:before {
content: "\f077";
}
.hpanel.collapsed.panel-collapse .panel-body {
border-width: 0 1px 1px 1px;
border-color: $border-color;
border-style: solid;
}
.hpanel.collapsed .hbuilt.panel-heading {
border-bottom: 1px solid $border-color;
}
body.fullscreen-panel-mode {
overflow-y: hidden;
}
.hpanel.fullscreen {
z-index: 2030;
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
overflow: auto;
margin-bottom: 0;
}
.hpanel.fullscreen .showhide {
display: none;
}
.hpanel.fullscreen .panel-body {
min-height: calc(100% - 77px);
}
这是 tool.module.js
文件,它使模板具有动画效果:
import angular from "angular";
var ToolResource = require("workflow/tool/tool.service");
class ToolListController {
// @ngInject
constructor($location, $stateParams, $state, tools) {
this.$location = $location;
this.$state = $state;
this.$stateParams = $stateParams;
this.tools = tools;
}
}
// @ngInject
function routesList($stateProvider) {
$stateProvider.state("tool-list", {
url: "/tool",
parent: "layout",
templateUrl: "/app/workflow/tool/toolList.html",
controller: "ToolListController",
controllerAs: "vm",
data: {
pageTitle: "Tool",
pareDesc: "List of tools, available for workflow construction.",
},
resolve: {
ToolResource: "ToolResource",
tools: function(ToolResource) {
return ToolResource.query().$promise;
}
}
});
}
module.exports = angular.module("tool", [])
.service('ToolResource', ToolResource)
.controller('ToolListController', ToolListController)
.config(routesList);
tool.service.js
:
module.exports = function ToolResource($resource) {
return $resource('/api/tool/:id', {id: '@id'});
}
答案:
社区很棒!
- 1.5 年前创建了此指令
- 12 天前修复了此错误 by Alexryan in his fork
- 10 天前我在 Whosebug 上发布了这个问题
- 8 天前我悬赏了这个问题
- 7 天前 ziscloud 批准了拉取请求
- 今天早上赏金到期,Walfrat 及时发现错误已修复
所以,是的,指令中的一个错误导致它在从服务器获取数据之前自行绘制。通过错误修复,我刚刚向指令添加了 load-when="vm.tools"
属性,现在它工作正常。
谢谢 Alexryan、ziscloud、Walfrat 和其他 commenters/answerers。 Whosebug 和 Github 让我开心!
由于您是异步加载数据(如评论中所述),因此您的 html 在包含任何数据之前呈现。这意味着该指令可能会过早触发(如果它试图根据数据进行调整)。通常,在这种情况下,您需要在依赖于数据加载的 html 部分抛出一个 ng-if(并在其位置显示加载 gif 或其他内容)。您可以 运行 正在定义的数据本身的 ng-if,或者维护一个单独的布尔值,一旦承诺得到解决,您就可以设置它。
你在使用这个指令吗? https://github.com/ziscloud/angular-footable/blob/master/src/angular-footable.js。这是一个自制的(意思不是由 footable 的编辑完成的)指令,所以它不能正确地实现与 Angularjs.
一起工作
看代码似乎你必须使用属性 load-when
如果你想延迟网格的初始化,即使你在你的状态中使用了 resolve 属性,也值得测试it.load-when
在开始时应该是一个空数组,并且会在数组不再为空后触发加载,但是绑定的数据不会用于我所看到的初始化。
注意:我自己无法设置正确的 plnkr,我不知道您使用的版本(以及与哪个 jQuery 版本一起使用)并且在线链接似乎不可用。
我在 ui-bootstrap 和 angular 1.4 中遇到以下奇怪行为。当我将 footable
table 指令放入名为 hpanel 的自定义 bootstrap 面板时,footable
最初比面板本身占据更多位置:
但是如果我调整屏幕大小(例如,通过折叠此处的开发人员工具面板),footable
指令会自行绘制并适合面板:
重要的是,我在使用 angular-c3
图表指令时遇到过类似的问题(它们加载不正确,超出了 hpanel 的大小,但在调整页面大小时表现良好),所以它可能不仅仅是一个损坏的指令。
你见过类似的东西吗?
详情:
下面是一个 HTML 模板,表示页面的非功能部分。我们有一个 hpanel
并且在其中应用了 table 和 angular-footable directive ^1.0.3。
这是模板 (toolList.html
):
<div class="content">
<div class="row">
<div class="col-lg-12">
<div class="hpanel">
<div class="panel-heading">
<div class="panel-tools">
<a class="showhide"><i class="fa fa-chevron-up"></i></a>
<a class="closebox"><i class="fa fa-times"></i></a>
</div>
Available tools.
</div>
<div class="panel-body">
<input type="text" class="form-control input-sm m-b-md" id="filter" placeholder="Search in table">
<table id="example1" class="footable table table-stripped toggle-arrow-tiny" data-page-size="8" data-filter=#filter>
<thead>
<tr>
<th data-toggle="true">Id</th>
<th>Class</th>
<th>Label</th>
<th>Description</th>
<th data-hide="all">Owner</th>
<th data-hide="all">Contributor</th>
<th data-hide="all">Inputs</th>
<th data-hide="all">Outputs</th>
<th data-hide="all">Base command</th>
<th data-hide="all">Arguments</th>
<th data-hide="all">Requirements</th>
<th data-hide="all">Hints</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="tool in vm.tools">
<td><a ui-sref="tool-detail({id: tool.id})">{{tool.id}}</a></td>
<td>{{tool.tool_class}}</td>
<td>{{tool.label}}</td>
<td>{{tool.description}}</td>
<td>{{tool.owner}}</td>
<td>{{tool.contributor}}</td>
<td>{{tool.baseCommand}}</td>
<td>{{tool.arguments}}</td>
<td>{{tool.requirements}}</td>
<td>{{tool.hints}}</td>
</tr>
</tbody>
<tfoot>
<tr>
<td colspan="5">
<ul class="pagination pull-right"></ul>
</td>
</tr>
</tfoot>
</table>
</div>
</div>
</div>
</div>
</div>
footable 指令用于隐藏 table 的某些列并在单击 table 行时显示它们。它还提供分页。它似乎在页面加载时不起作用,但是当我调整页面大小时并且屏幕大小超过媒体类型边距(因此从中等大小的屏幕变成大屏幕 bootstrap css 条款),分页按钮出现,隐藏的列被隐藏。
以下是我在主模块中导入 footable
指令的方法 app.js
:
require("footable/js/footable");
require("footable/js/footable.filter");
require("footable/js/footable.striping");
require("footable/js/footable.sort");
require("footable/js/footable.paginate");
require("footable/css/footable.core.css")
require("angular-footable");
angular.module("app", [
...,
"ui.footable",
])
我使用 webpack
加载所有这些模块,并使用 bower
安装依赖项。
hpanel 只是一个 scss
class,这里是它的定义:
/* Panels */
.hpanel > .panel-heading {
color: inherit;
font-weight: 600;
padding: 10px 4px;
transition: all .3s;
border: 1px solid transparent;
}
.hpanel .hbuilt.panel-heading {
border-bottom: none;
}
.hpanel > .panel-footer, .hpanel > .panel-section {
color: inherit;
border: 1px solid $border-color;
border-top: none;
font-size: 90%;
background: $color-bright;
padding: 10px 15px;
}
.hpanel.panel-collapse > .panel-heading, .hpanel .hbuilt {
background: #fff;
border-color: $border-color;
border: 1px solid $border-color;
padding: 10px 10px;
border-radius: 2px;
}
.hpanel .panel-body {
background: #fff;
border: 1px solid $border-color;
border-radius: 2px;
padding: 20px;
position: relative;
}
.hpanel.panel-group .panel-body:first-child {
border-top: 1px solid $border-color;
}
.hpanel.panel-group .panel-body {
border-top: none;
}
.panel-collapse .panel-body {
border: none;
}
.hpanel {
background-color: none;
border: none;
box-shadow: none;
margin-bottom: 25px;
}
.panel-tools {
display: inline-block;
float: right;
margin-top: 0;
padding: 0;
position: relative;
}
.hpanel .alert {
margin-bottom: 0;
border-radius: 0;
border: 1px solid $border-color;
border-bottom: none;
}
.panel-tools a {
margin-left: 5px;
color: lighten($color-text, 20%);
cursor: pointer;
}
.hpanel.hgreen .panel-body {
border-top: 2px solid $color-green;
}
.hpanel.hblue .panel-body {
border-top: 2px solid $color-blue;
}
.hpanel.hyellow .panel-body {
border-top: 2px solid $color-yellow;
}
.hpanel.hviolet .panel-body {
border-top: 2px solid $color-violet;
}
.hpanel.horange .panel-body {
border-top: 2px solid $color-orange;
}
.hpanel.hred .panel-body {
border-top: 2px solid $color-red;
}
.hpanel.hreddeep .panel-body {
border-top: 2px solid $color-red-deep;
}
.hpanel.hnavyblue .panel-body {
border-top: 2px solid $color-navy-blue;
}
.hpanel.hbggreen .panel-body {
background: $color-green;
color: #fff;
border:none;
}
.hpanel.hbgblue .panel-body {
background: $color-blue;
color: #fff;
border:none;
}
.hpanel.hbgyellow .panel-body {
background: $color-yellow;
color: #fff;
border:none;
}
.hpanel.hbgviolet .panel-body {
background: $color-violet;
color: #fff;
border:none;
}
.hpanel.hbgorange .panel-body {
background: $color-orange;
color: #fff;
border:none;
}
.hpanel.hbgred .panel-body {
background: $color-red;
color: #fff;
border:none;
}
.hpanel.hbgreddeep .panel-body {
background: $color-red-deep;
color: #fff;
border:none;
}
.hpanel.hbgnavyblue .panel-body {
background: $color-navy-blue;
color: #fff;
border:none;
}
.panel-group .panel-heading {
background-color: $color-bright;
}
.small-header .hpanel {
margin-bottom: 0;
}
.small-header {
padding: 0 !important;
}
.small-header .panel-body {
padding: 15px 25px;
border-right: none;
border-left: none;
border-top: none;
border-radius: 0;
// background: $color-bright;
}
.panel-body h5, .panel-body h4 {
font-weight: 600;
}
.small-header .panel-body h2 {
font-size: 14px;
font-weight: 600;
text-transform: uppercase;
margin: 0 0 0 0;
}
.small-header .panel-body small {
color: lighten($color-text, 10%);
}
.hbreadcrumb {
padding: 2px 0px;
margin-top: 6px;
margin-bottom: 0px;
list-style: none;
background-color: #fff;
font-size: 11px;
> li {
display: inline-block;
+ li:before {
padding: 0 5px;
color: $color-navy-blue;
}
}
> .active {
color: lighten($color-text,20%);
}
}
.wrapper {
padding: 10px 20px;
}
.hpanel.collapsed .panel-body, .hpanel.collapsed .panel-footer {
display: none;
}
.hpanel.collapsed .fa.fa-chevron-up:before {
content: "\f078";
}
.hpanel.collapsed .fa.fa-chevron-down:before {
content: "\f077";
}
.hpanel.collapsed.panel-collapse .panel-body {
border-width: 0 1px 1px 1px;
border-color: $border-color;
border-style: solid;
}
.hpanel.collapsed .hbuilt.panel-heading {
border-bottom: 1px solid $border-color;
}
body.fullscreen-panel-mode {
overflow-y: hidden;
}
.hpanel.fullscreen {
z-index: 2030;
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
overflow: auto;
margin-bottom: 0;
}
.hpanel.fullscreen .showhide {
display: none;
}
.hpanel.fullscreen .panel-body {
min-height: calc(100% - 77px);
}
这是 tool.module.js
文件,它使模板具有动画效果:
import angular from "angular";
var ToolResource = require("workflow/tool/tool.service");
class ToolListController {
// @ngInject
constructor($location, $stateParams, $state, tools) {
this.$location = $location;
this.$state = $state;
this.$stateParams = $stateParams;
this.tools = tools;
}
}
// @ngInject
function routesList($stateProvider) {
$stateProvider.state("tool-list", {
url: "/tool",
parent: "layout",
templateUrl: "/app/workflow/tool/toolList.html",
controller: "ToolListController",
controllerAs: "vm",
data: {
pageTitle: "Tool",
pareDesc: "List of tools, available for workflow construction.",
},
resolve: {
ToolResource: "ToolResource",
tools: function(ToolResource) {
return ToolResource.query().$promise;
}
}
});
}
module.exports = angular.module("tool", [])
.service('ToolResource', ToolResource)
.controller('ToolListController', ToolListController)
.config(routesList);
tool.service.js
:
module.exports = function ToolResource($resource) {
return $resource('/api/tool/:id', {id: '@id'});
}
答案: 社区很棒!
- 1.5 年前创建了此指令
- 12 天前修复了此错误 by Alexryan in his fork
- 10 天前我在 Whosebug 上发布了这个问题
- 8 天前我悬赏了这个问题
- 7 天前 ziscloud 批准了拉取请求
- 今天早上赏金到期,Walfrat 及时发现错误已修复
所以,是的,指令中的一个错误导致它在从服务器获取数据之前自行绘制。通过错误修复,我刚刚向指令添加了 load-when="vm.tools"
属性,现在它工作正常。
谢谢 Alexryan、ziscloud、Walfrat 和其他 commenters/answerers。 Whosebug 和 Github 让我开心!
由于您是异步加载数据(如评论中所述),因此您的 html 在包含任何数据之前呈现。这意味着该指令可能会过早触发(如果它试图根据数据进行调整)。通常,在这种情况下,您需要在依赖于数据加载的 html 部分抛出一个 ng-if(并在其位置显示加载 gif 或其他内容)。您可以 运行 正在定义的数据本身的 ng-if,或者维护一个单独的布尔值,一旦承诺得到解决,您就可以设置它。
你在使用这个指令吗? https://github.com/ziscloud/angular-footable/blob/master/src/angular-footable.js。这是一个自制的(意思不是由 footable 的编辑完成的)指令,所以它不能正确地实现与 Angularjs.
一起工作看代码似乎你必须使用属性 load-when
如果你想延迟网格的初始化,即使你在你的状态中使用了 resolve 属性,也值得测试it.load-when
在开始时应该是一个空数组,并且会在数组不再为空后触发加载,但是绑定的数据不会用于我所看到的初始化。
注意:我自己无法设置正确的 plnkr,我不知道您使用的版本(以及与哪个 jQuery 版本一起使用)并且在线链接似乎不可用。