ChatGPT解决这个技术问题 Extra ChatGPT

如何在页面加载时执行 AngularJS 控制器功能?

目前我有一个允许搜索和显示结果的 Angular.js 页面。用户单击搜索结果,然后单击返回按钮。我希望再次显示搜索结果,但我不知道如何触发搜索执行。这是详细信息:

我的 Angular.js 页面是一个搜索页面,带有一个搜索字段和一个搜索按钮。用户可以手动输入查询并按下按钮,然后触发 ajax 查询并显示结果。我用搜索词更新 URL。这一切都很好。

用户点击搜索结果并被带到不同的页面 - 这也很好。

用户单击返回按钮,然后返回我的角度搜索页面,并显示正确的 URL,包括搜索词。一切正常。

我已将搜索字段值绑定到 URL 中的搜索词,因此它包含预期的搜索词。一切正常。

如何在无需用户按下“搜索按钮”的情况下再次执行搜索功能?如果是 jquery,那么我将在 documentready 函数中执行一个函数。我看不到 Angular.js 的等价物。

您在使用 $routepProvider 吗?使用它连接到应用程序中为搜索结果提供数据的服务。不要像 jQuery 那样用 document.ready 的术语来思考。如果不了解您目前如何连接搜索,很难提供很多帮助

D
Dmitry Evseev

一方面,正如@Mark-Rajcok 所说,您可以摆脱私有内部功能:

// at the bottom of your controller
var init = function () {
   // check if there is query in url
   // and fire search in case its value is not empty
};
// and fire it after definition
init();

您还可以查看 ng-init 指令。实现将很像:

// register controller in html
<div data-ng-controller="myCtrl" data-ng-init="init()"></div>

// in controller
$scope.init = function () {
    // check if there is query in url
    // and fire search in case its value is not empty
};

但请注意它作为 angular documentation implies (since v1.2) 不要使用 ng-init。但是 imo 这取决于您的应用程序的架构。

当我想将值从后端传递到 Angular 应用程序时,我使用了 ng-init

<div data-ng-controller="myCtrl" data-ng-init="init('%some_backend_value%')"></div>

@Duke,您不能将 init() 函数的内容放在控制器的底部吗?即,为什么需要使用 ng-init 并具有 init() 函数?当用户点击后退按钮时,我假设您正在切换视图,因此创建并执行了一个新的 myCtrl 控制器。
虽然这个解决方案有效,但我投了反对票,因为 ng-init 文档建议不要这样做。具体来说,“ngInit 的唯一适当用途是对 ngRepeat 的特殊属性进行别名化,如下面的演示所示。除了这种情况,您应该使用控制器而不是 ngInit 来初始化作用域上的值。”
控制器在 html 就位后被实例化。
如果控制器在其他页面中重用但您只想在特定页面上触发它怎么办?
@RobertoLinares 我个人认为指令是可重用功能的更好地方。您可以有一个带有 init 参数的指令:<div smth on-init="doWhatever()">。当然,这取决于特定的用例。
h
holographic-principle

尝试这个?

$scope.$on('$viewContentLoaded', function() {
    //call it here
});

感谢您的回复,但德米特里的回答与我正在寻找的完全匹配。进一步的研究似乎建议反对 $viewContentLoaded
用例只是不同。我也一直使用马克的方法。
对于我的用例,这是一个完美的解决方案。我们需要自动选择文本以鼓励用户复制它。该页面可以多次重新加载/重新访问,因此 $viewContentLoaded 是完全匹配的。谢谢!
是否有可能执行多次?我的行为似乎在模仿...
这个对我不起作用,但 $scope.$watch 起作用了。主要区别是什么?
O
Owen Blacker

我永远无法让 $viewContentLoaded 为我工作,并且 ng-init 真的应该只在 ng-repeat 中使用(根据文档),并且如果代码依赖于直接在控制器中调用函数可能会导致错误尚未定义的元素。

这就是我所做的,它对我有用:

$scope.$on('$routeChangeSuccess', function () {
  // do something
});

除非您使用 ui-router。然后是:

$scope.$on('$stateChangeSuccess', function () {
  // do something
});

你太棒了,我的朋友。
正是我需要的。我真的是在找这个两天!
每次更改 url 中的参数时都会触发 $scope.$on('$routeChangeSuccess'(例如通过 $location),因此您可以只使用 $scope.$on('$locationChangeSuccess'。如果您在页面加载/重新加载时需要一些触发器,您可以按照此处的建议使用 $scope.$watch('$viewContentLoaded'。它不会在 url 参数更改期间触发。
使用 AngularJS 1.17.2,内部控制器 $routeChangeSuccess 工作得非常好......万岁 adam0101......
C
Carlos Trujillo
angular.element(document).ready(function () {

    // your code here

});

必须是公认的答案,这是更安全的方法
如果我们不使用 $scope 而是使用 this,这很好。
这需要去哪里?我在我的模板中有它,它没有触发。
在这种情况下注入 $document 不是最好的吗? angular.element($document).ready...
解释将不胜感激
g
guico

Dimitri 的/Mark 的解决方案对我不起作用,但使用 $timeout 函数似乎可以很好地确保您的代码仅在呈现标记后运行。

# Your controller, including $timeout

var $scope.init = function(){
 //your code
}

$timeout($scope.init)

希望能帮助到你。


最后。这是唯一对我有用的。谢谢。
这行得通。也不要忘记用 $timeout.cancel(timer) 清除超时,你有 var timer = $timeout($scope.init, milliseconds);一旦你的初始化完成。另外,我认为 $scope 不应该在你上面的代码中有一个 'var' def
这应该是公认的答案。这是唯一对我有用的(尝试了上面的所有答案)。如果您正在等待 iframe 加载,它甚至可以工作。
C
CodeOverRide

如果你想观察 viewContentLoaded DOM 对象的变化然后做一些事情,你可以这样做。使用 $scope.$on 也有效,但不同的是,尤其是当您在路由上使用一页模式时。

 $scope.$watch('$viewContentLoaded', function(){
    // do something
 });

具体来说,如果您使用 $rootScope.$watch 而不是 $rootScope.$on 它不会在路由更改时触发,因此您可以使用特定于初始页面加载的逻辑。
m
mcgraw

您可以使用 Angular 的 $window 对象:

$window.onload = function(e) {
  //your magic here
}

C
Community

另一种选择:

var myInit = function () {
    //...
};
angular.element(document).ready(myInit);

(通过 https://stackoverflow.com/a/30258904/148412


C
Chipe

如果您有一个特定于该页面的控制器,还有另一种选择:

(function(){
    //code to run
}());

A
Anik Islam Abhi

使用 $routeProvider 时,您可以解析 .state 并引导您的服务。这就是说,你要加载控制器和视图,只有在解决你的服务之后:

用户界面路由

 .state('nn', {
        url: "/nn",
        templateUrl: "views/home/n.html",
        controller: 'nnCtrl',
        resolve: {
          initialised: function (ourBootstrapService, $q) {

            var deferred = $q.defer();

            ourBootstrapService.init().then(function(initialised) {
              deferred.resolve(initialised);
            });
            return deferred.promise;
          }
        }
      })

服务

function ourBootstrapService() {

 function init(){ 
    // this is what we need
 }
}

K
Kailas

发现 Dmitry Evseev 的回答非常有用。

案例1:单独使用angularJs:
要在页面加载时执行方法,您可以在视图中使用ng-init并在控制器中声明init方法,但使用较重的函数不是推荐,根据 angular Docs on ng-init

可以滥用该指令在模板中添加不必要的逻辑量。 ngInit 只有少数合适的用途,例如用于别名 ngRepeat 的特殊属性,如下面的演示所示;以及通过服务器端脚本注入数据。除了这几种情况,您应该使用控制器而不是 ngInit 来初始化作用域上的值。

HTML:

<div ng-controller="searchController()">
    <!-- renaming view code here, including the search box and the buttons -->
</div>

控制器:

app.controller('SearchCtrl', function(){

    var doSearch = function(keyword){
        //Search code here
    }

    doSearch($routeParams.searchKeyword);
})

警告:不要将此控制器用于另一个意图不同的视图,因为它也会导致搜索方法在那里执行。

案例 2:使用 Ionic:
上面的代码可以工作,只需确保在 route.js 中禁用视图缓存,如下所示:

路由.js

.state('app', {
    url           : '/search',
    cache         : false, //disable caching of the view here
    templateUrl   : 'templates/search.html'   ,
    controller    : 'SearchCtrl'
  })

希望这可以帮助


这只有一个,在最底部,很高兴我一路走下去,cache: false为我做了 - 谢谢!
G
Ginko Balboa

我遇到了同样的问题,只有这个解决方案对我有用(它在加载完整的 DOM 后运行一个函数)。我在页面加载后使用它来滚动锚定:

angular.element(window.document.body).ready(function () {

                        // Your function that runs after all DOM is loaded

                    });

m
marc_s

您可以将搜索结果保存在一个通用服务中,该服务可以在任何地方使用并且导航到另一个页面时不会清除,然后您可以使用保存的数据设置搜索结果以单击返回按钮

function search(searchTerm) {
    // retrieve the data here;
    RetrievedData = CallService();
    CommonFunctionalityService.saveSerachResults(RetrievedData);
} 

对于您的后退按钮

function Backbutton() {
    RetrievedData = CommonFunctionalityService.retrieveResults();
}

U
Uditha Prasad

在自初始化函数中调用初始方法。

(function initController() {

    // do your initialize here

})();