我正在使用 ng-if 来显示和隐藏一个元素。当该元素出现时,我想调用一个服务,该服务在新元素内滚动到某个子元素(按 Id)。问题是,如果我在将元素设置为可见后立即尝试调用我的服务函数,那么 DOM 似乎还没有准备好。
var myApp = angular.module('myApp',[]);
myApp.factory("ScrollService", function () {
return {
scroll: function (id) {
console.log(document.getElementById(id));
}
};
});
function MyCtrl($scope, ScrollService) {
$scope.visible = false;
$scope.toggleVisibility = function () {
$scope.visible = !$scope.visible;
if ($scope.visible) {
ScrollService.scroll("myId"); //output: null
}
};
}
document.getElementById() 将始终导致 null。
这也是一个 fiddle ,演示了这个问题:http://jsfiddle.net/Dpuq2/
那么有没有办法,在被 ng-if 操作后 DOM 准备就绪时立即触发一个函数?
编辑
使用 MinkoGechev 的 fiddle ,我能够在更真实的环境中重现我的错误,并使用指令而不是服务:FIDDLE
问题似乎出现了,因为我在 ng-if-container 中使用了 ng-repeat:
<div ng-controller="MyCtrl">
<div ng-if="visible">
<div id="myId" data-scroll="itemId">
<div id="xy"></div>
<div ng-repeat="item in items" id="{{ item.number }}">{{ item.number }}</div>
</div>
</div>
<button ng-click="toggleVisibility()">toggle</button>
</div>
这是相应的指令加上 Controller :
var myApp = angular.module('myApp',[]);
myApp.directive("scroll", function () {
return {
scope: {
scroll: '='
},
link: function (scope) {
scope.$watch('scroll', function (v) {
console.log(v, document.getElementById(scope.scroll));
});
},
transclude: true,
template: "<div ng-transclude></div>"
};
});
function MyCtrl($scope) {
$scope.visible = false;
$scope.itemId = "";
$scope.items = [];
for (var i = 1; i < 10; i++) {
$scope.items.push({
number: i,
text: "content " + i
});
}
$scope.toggleVisibility = function () {
$scope.visible = !$scope.visible;
if ($scope.visible) {
$scope.itemId = "3";
}
};
}
因此,只要我切换容器的可见性,我就会设置要滚动到的元素的 ID:
$scope.itemId = "3"
如果我使用 1 到 10 中的一个数字(由 ng-repeat 创建的元素的 ID),它将失败。如果我使用“xy”(位于 ng-repeat 元素旁边的一个元素的 ID),它会成功。
最佳答案
以下是如何使用指令实现您正在寻找的效果:
var myApp = angular.module('myApp',[]);
myApp.directive("scroll", function () {
return {
scope: {
scroll: '='
},
link: function (scope) {
scope.$watch('scroll', function (v) {
//The value is true, so the element is visible
console.log(v, document.getElementById('myId'));
});
}
};
});
function MyCtrl($scope) {
$scope.visible = false;
$scope.toggleVisibility = function () {
$scope.visible = !$scope.visible;
};
}
这里是 DEMO (打开您的控制台以查看日志)。
注意:AngularJS 强制分离关注点,从而使代码更具可读性和可维护性。使用“Angular 方式”时应遵循的规则之一是将所有 DOM 操作ONLY放在指令中。
关于javascript - angularJS:WAITING ng-if 完成,以确保 DOM 已准备就绪,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19758236/
我正在检查一个Rails项目。在ERubyHTML模板页面上,我看到了这样几行:我不明白为什么不这样写:在这种情况下,||=和ifnil?有什么区别? 最佳答案 在这种特殊情况下没有区别,但可能是出于习惯。每当我看到nil?被使用时,它几乎总是使用不当。在Ruby中,很少有东西在逻辑上是假的,只有文字false和nil是。这意味着像if(!x.nil?)这样的代码几乎总是更好地表示为if(x)除非期望x可能是文字false。我会将其切换为||=false,因为它具有相同的结果,但这在很大程度上取决于偏好。唯一的缺点是赋值会在每次运行
假设我在Ruby中有这个each循环。@list.each{|i|putsiifi>10breakend}我想循环遍历列表直到满足条件。这让我感到“不像Ruby”,因为我是Ruby的新手,是否有Ruby方法可以做到这一点? 最佳答案 您可以使用Enumerable#detect或Enumerable#take_while,取决于您想要的结果。@list.detect{|i|putsii>10}#Returnsthefirstelementgreaterthan10,ornil.正如其他人所指出的,更好的风格是先进行子选择,然后再对其
在我做的一些网络开发中,我有多个操作开始,比如对外部API的GET请求,我希望它们同时开始,因为一个不依赖另一个的结果。我希望事情能够在后台运行。我找到了concurrent-rubylibrary这似乎运作良好。通过将其混合到您创建的类中,该类的方法具有在后台线程上运行的异步版本。这导致我编写如下代码,其中FirstAsyncWorker和SecondAsyncWorker是我编写的类,我在其中混合了Concurrent::Async模块,并编写了一个名为“work”的方法来发送HTTP请求:defindexop1_result=FirstAsyncWorker.new.async.
ActiveRecord用于在每次调用保存方法时调用after_save回调,即使模型没有更改并且没有生成插入/更新查询也是如此。这实际上是默认行为。在大多数情况下这没问题。但是一些after_save回调对模型是否实际保存的事情很敏感。有没有办法确定模型是否实际保存在after_save中?我正在运行以下测试代码:classStage 最佳答案 ActiveRecordusetocallafter_savecallbackeachtimesavemethodiscalledevenifthemodelwasnotchangedan
我遇到了一个非常奇怪的问题,我很难解决。在我看来,我有一个与data-remote="true"和data-method="delete"的链接。当我单击该链接时,我可以看到对我的Rails服务器的DELETE请求。返回的JS代码会更改此链接的属性,其中包括href和data-method。再次单击此链接后,我的服务器收到了对新href的请求,但使用的是旧的data-method,即使我已将其从DELETE到POST(它仍然发送一个DELETE请求)。但是,如果我刷新页面,HTML与"new"HTML相同(随返回的JS发生变化),但它实际上发送了正确的请求类型。这就是这个问题令我困惑的
在Ruby(尤其是Rails)中,您经常需要检查某物是否存在,然后对其执行操作,例如:if@objects.any?puts"Wehavetheseobjects:"@objects.each{|o|puts"hello:#{o}"end这是最短的,一切都很好,但是如果你有@objects.some_association.something.hit_database.process而不是@objects呢?我将不得不在if表达式中重复两次,如果我不知道实现细节并且方法调用很昂贵怎么办?显而易见的选择是创建一个变量,然后测试它,然后处理它,但是你必须想出一个变量名(呃),它也会在内存中
如何在Ruby的if语句中检查bash命令的返回值(true/false)。我想要这样的东西,if("/usr/bin/fswscell>/dev/null2>&1")has_afs="true"elsehas_afs="false"end它会提示以下错误含义,它总是返回true。(irb):5:warning:stringliteralincondition正确的语法是什么?更新:/usr/bin/fswscell寻找afs安装和运行状态。它会抛出这样的字符串,Thisworkstationbelongstocell如果afs没有运行,命令以状态1退出 最
我最近与一位同事讨论了以下Ruby语法:value=ifa==0"foo"elsifa>42"bar"else"fizz"end我个人并没有看到太多这种逻辑,但我的同事指出,这实际上是一种相当普遍的Rubyism。我试着用谷歌搜索这个主题,但没有找到任何文章、页面或SO问题来讨论它,这让我相信这可能是一种非常实际的技术。然而,另一位同事发现语法令人困惑,而是将上面的逻辑写成这样:ifa==0value="foo"elsifa>42value="bar"elsevalue="fizz"end缺点是value=的重复声明和隐式elsenil的丢失,如果我们想使用它的话。这也感觉它与Ruby
一边学习thisRailscast我从Rack中看到了以下源代码:defself.middleware@middleware||=beginm=Hash.new{|h,k|h[k]=[]}m["deployment"].concat[[Rack::ContentLength],[Rack::Chunked],logging_middleware]m["development"].concatm["deployment"]+[[Rack::ShowExceptions],[Rack::Lint]]mendend我的问题是关于第三行。什么是传递block{|h,k|h[k]=[]}到Has
在纯Rubyirb中,不能输入{if:1}。该语句不会终止,因为irb认为if不是符号,而是if语句的开始。那么为什么Rails可以有before_filter接受if作为参数?该指南的代码如下:classOrderunless也会发生同样的事情。 最佳答案 这是一个irb问题,而不是Ruby。bash=>ruby-e"puts({if:1})"bash=#{:if=>1}您可以改用pry。它将正确读取输入。https://github.com/pry/pry 关于ruby-on-rai