草庐IT

javascript - angularJS:WAITING ng-if 完成,以确保 DOM 已准备就绪

coder 2024-07-25 原文

我正在使用 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/

有关javascript - angularJS:WAITING ng-if 完成,以确保 DOM 已准备就绪的更多相关文章

  1. ruby-on-rails - `a ||= b` 和 `a = b if a.nil 之间的区别? - 2

    我正在检查一个Rails项目。在ERubyHTML模板页面上,我看到了这样几行:我不明白为什么不这样写:在这种情况下,||=和ifnil?有什么区别? 最佳答案 在这种特殊情况下没有区别,但可能是出于习惯。每当我看到nil?被使用时,它几乎总是使用不当。在Ruby中,很少有东西在逻辑上是假的,只有文字false和nil是。这意味着像if(!x.nil?)这样的代码几乎总是更好地表示为if(x)除非期望x可能是文字false。我会将其切换为||=false,因为它具有相同的结果,但这在很大程度上取决于偏好。唯一的缺点是赋值会在每次运行

  2. ruby - ruby 中有 each_if 吗? - 2

    假设我在Ruby中有这个each循环。@list.each{|i|putsiifi>10breakend}我想循环遍历列表直到满足条件。这让我感到“不像Ruby”,因为我是Ruby的新手,是否有Ruby方法可以做到这一点? 最佳答案 您可以使用Enumerable#detect或Enumerable#take_while,取决于您想要的结果。@list.detect{|i|putsii>10}#Returnsthefirstelementgreaterthan10,ornil.正如其他人所指出的,更好的风格是先进行子选择,然后再对其

  3. ruby-on-rails - 在 Ruby on Rails 中发送响应之前如何等待多个异步操作完成? - 2

    在我做的一些网络开发中,我有多个操作开始,比如对外部API的GET请求,我希望它们同时开始,因为一个不依赖另一个的结果。我希望事情能够在后台运行。我找到了concurrent-rubylibrary这似乎运作良好。通过将其混合到您创建的类中,该类的方法具有在后台线程上运行的异步版本。这导致我编写如下代码,其中FirstAsyncWorker和SecondAsyncWorker是我编写的类,我在其中混合了Concurrent::Async模块,并编写了一个名为“work”的方法来发送HTTP请求:defindexop1_result=FirstAsyncWorker.new.async.

  4. ruby-on-rails - rails : check if the model was really saved in after_save - 2

    ActiveRecord用于在每次调用保存方法时调用after_save回调,即使模型没有更改并且没有生成插入/更新查询也是如此。这实际上是默认行为。在大多数情况下这没问题。但是一些after_save回调对模型是否实际保存的事情很敏感。有没有办法确定模型是否实际保存在after_save中?我正在运行以下测试代码:classStage 最佳答案 ActiveRecordusetocallafter_savecallbackeachtimesavemethodiscalledevenifthemodelwasnotchangedan

  5. ruby-on-rails - 使用 javascript 更改数据方法不会更改 ajax 调用用户的什么方法? - 2

    我遇到了一个非常奇怪的问题,我很难解决。在我看来,我有一个与data-remote="true"和data-method="delete"的链接。当我单击该链接时,我可以看到对我的Rails服务器的DELETE请求。返回的JS代码会更改此链接的属性,其中包括href和data-method。再次单击此链接后,我的服务器收到了对新href的请求,但使用的是旧的data-method,即使我已将其从DELETE到POST(它仍然发送一个DELETE请求)。但是,如果我刷新页面,HTML与"new"HTML相同(随返回的JS发生变化),但它实际上发送了正确的请求类型。这就是这个问题令我困惑的

  6. ruby - 你会如何在 Ruby 中表达成语 "with this object, if it exists, do this"? - 2

    在Ruby(尤其是Rails)中,您经常需要检查某物是否存在,然后对其执行操作,例如:if@objects.any?puts"Wehavetheseobjects:"@objects.each{|o|puts"hello:#{o}"end这是最短的,一切都很好,但是如果你有@objects.some_association.something.hit_database.process而不是@objects呢?我将不得不在if表达式中重复两次,如果我不知道实现细节并且方法调用很昂贵怎么办?显而易见的选择是创建一个变量,然后测试它,然后处理它,但是你必须想出一个变量名(呃),它也会在内存中

  7. ruby - 在 Ruby 的 if 语句中检查 bash 命令 - 2

    如何在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退出 最

  8. ruby - 变量赋值后的 if 语句 - 有多常见? - 2

    我最近与一位同事讨论了以下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

  9. Ruby:行 "m = Hash.new {|h,k| h[k] = []}"完成了什么而 "Hash.new"没有完成? - 2

    一边学习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

  10. ruby-on-rails - 为什么 Rails 可以使用 `if` 作为哈希键但在 Ruby 中不能 - 2

    在纯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

随机推荐