ভিউ লোড হওয়ার পরে অ্যাংুলারজেএস সূচনা কোড চালানো হচ্ছে


93

আমি যখন কোনও ভিউ লোড করি, আমি এর সাথে সম্পর্কিত নিয়ামকটিতে কিছু সূচনা কোড চালাতে চাই।

এটি করার জন্য, আমি আমার ভিউয়ের মূল উপাদানটিতে এনজি-ডাইরেক্ট ব্যবহার করেছি:

<div ng-init="init()">
  blah
</div>

এবং নিয়ামক মধ্যে:

$scope.init = function () {
    if ($routeParams.Id) {
        //get an existing object
        });
    } else {
       //create a new object
    }

    $scope.isSaving = false;
}

প্রথম প্রশ্ন: এটি কি এটি সঠিক উপায়?

পরবর্তী জিনিস, ঘটনার ক্রমগুলি নিয়ে আমার সমস্যা আছে। ভিউতে আমার কাছে একটি 'সেভ' বোতাম রয়েছে, যা ng-disabledনির্দেশিকাটি এর মতো ব্যবহার করে :

<button ng-click="save()" ng-disabled="isClean()">Save</button>

isClean()ফাংশন নিয়ামক সংজ্ঞায়িত হয়:

$scope.isClean = function () {
    return $scope.hasChanges() && !$scope.isSaving;
}

আপনি দেখতে পাচ্ছেন, এটি $scope.isSavingপতাকাটি ব্যবহার করে যা init()ফাংশনে শুরু হয়েছিল ।

সমস্যা: যখন দৃশ্য লোড হয়, isClean ফাংশন বলা হয় সামনেinit() ফাংশন, অত: পর পতাকা isSavingহয় undefined। আমি তা আটকাতে কী করতে পারি?

উত্তর:


137

যখন আপনার ভিউ লোড হয়, তেমনি এর সাথে সম্পর্কিত নিয়ামকও থাকে। ব্যবহারের পরিবর্তে ng-init, init()আপনার নিয়ামকটিতে কেবল আপনার পদ্ধতিটি কল করুন :

$scope.init = function () {
    if ($routeParams.Id) {
        //get an existing object
    } else {
        //create a new object
    }
    $scope.isSaving = false;
}
...
$scope.init();

যেহেতু আপনার নিয়ামক আগে চলে তাই ng-initএটি আপনার দ্বিতীয় সমস্যাও সমাধান করে।

ফিডল


John David Fiveউল্লিখিত হিসাবে , আপনি $scopeএই পদ্ধতিটি ব্যক্তিগত করার জন্য এটির সাথে সংযুক্ত করতে চাইবেন না ।

var init = function () {
    // do something
}
...
init();

JsFizz দেখুন


আপনি যদি নির্দিষ্ট ডেটা প্রিসেট হওয়ার জন্য অপেক্ষা করতে চান, হয় সেই ডেটা অনুরোধটিকে কোনও সংকল্পের দিকে নিয়ে যান বা সেই সংগ্রহ বা বস্তুতে একজন প্রহরী যুক্ত করুন এবং যখন আপনার ডেটা আপনার ডিআর মানদণ্ডের সাথে মিলিত হয় তখন আপনার init পদ্ধতিটি কল করুন। আমার ডেটা প্রয়োজনীয়তাগুলি একবার পূরণ করার পরে আমি সাধারণত নজরদারি সরিয়ে ফেলি যাতে থের ফাংশনটি এলোমেলোভাবে পুনরায় চালায় না যদি আপনার দেখার ডেটা পরিবর্তন হয় এবং আপনার আর ডি পদ্ধতিটি চালানোর জন্য আপনার মানদণ্ড পূরণ করে।

var init = function () {
    // do something
}
...
var unwatch = scope.$watch('myCollecitonOrObject', function(newVal, oldVal){
                    if( newVal && newVal.length > 0) {
                        unwatch();
                        init();
                    }
                });

8
ইনিশিয়ালেশন চালানোর জন্য যদি কিছু মডেল থেকে আপনার ডেটা প্রয়োজন? অথবা পৃষ্ঠায় রেন্ডারিংয়ের সময় কেবলমাত্র কিছু ডেটা পাওয়া যায়, যাতে আরম্ভের কাজ করতে পারে?
ইউজিন

39
কোনও init ফাংশনটি $ স্কোপের সাথে সংযুক্ত করার প্রয়োজন হয় না। আপনার init ফাংশনটি ব্যক্তিগত করুন। আপনি কখনই চাইবেন না যে কোনও ইনিশ ফাংশন একাধিকবার চালিত হোক তাই এটিকে $ সুযোগে প্রকাশ করবেন না।
জন ডেভিড পাঁচ

4
আমার ভিউটি দেখানো হলে আমি আর ডি ফাংশনটি চালাতে চাই তবে আমার কোনও ক্লু নেই যে কীভাবে, ফাংশনটি কেবল একবার চালানো হবে। কোনও ধারণা আমি কীভাবে এটি প্রতিটি পৃষ্ঠা / টেম্পলেট লোডে চালাতে পারি?
জোরে

9
আমি কৌণিক বিশেষজ্ঞ নই, তবে এই পদ্ধতির পরীক্ষার জন্য সফলতা অর্জন করা, যেহেতু থিম () কে কেবল নিয়ামক ইনস্ট্যান্টেশন বলা হয় ... অন্য কথায়, যখন আপনাকে নিয়ামকের একটি একক পদ্ধতি পরীক্ষা করার দরকার হয়, থ্রি (এছাড়াও) বলা হয়। .ব্রেকিং!
ওয়াগনার লিওনার্দি

4
@ ওয়াগনারলিয়োনার্ডি যা বলেছে। এই পদ্ধতির সাহায্যে আপনার "ব্যক্তিগত" init () পদ্ধতিটি পরীক্ষা করা বেশ কঠিন হয়ে যায়।
স্টিভেন রজার্স

37

AngularJS 1.5 যেহেতু আমাদের ব্যবহার করা উচিত$onInit যা কোনও AngularJS উপাদানগুলিতে উপলব্ধ। V1.5 এর পূর্বনির্ধারিত উপায়ে উপাদান উপাদান লাইফসাইकल ডকুমেন্টেশন থেকে নেওয়া হয়েছে :

I অনিট () - কোনও উপাদানটির সমস্ত কন্ট্রোলার তৈরি হওয়ার পরে এবং তাদের বাইন্ডিংগুলি শুরু করার পরে (এবং এই উপাদানটির নির্দেশনার জন্য প্রাক এবং পোস্ট লিঙ্কিংয়ের আগে) প্রতিটি কন্ট্রোলারে কল করা হয়। আপনার নিয়ামকের জন্য আরম্ভের কোডটি রাখার জন্য এটি একটি ভাল জায়গা।

var myApp = angular.module('myApp',[]);
myApp.controller('MyCtrl', function ($scope) {

    //default state
    $scope.name = '';

    //all your init controller goodness in here
    this.$onInit = function () {
      $scope.name = 'Superhero';
    }
});

>> ফিডাল ডেমো


উপাদান জীবনচক্র ব্যবহারের একটি উন্নত উদাহরণ:

উপাদান উপাদানটি একটি ভাল পদ্ধতিতে উপাদান উপাদান হ্যান্ডেল করার ক্ষমতা দেয়। এটি আমাদের একটি উপাদান যেমন "init", "পরিবর্তন" বা "ধ্বংস" এর জন্য ইভেন্টগুলি তৈরি করতে সহায়তা করে। এইভাবে আমরা এমন উপাদানগুলি পরিচালনা করতে সক্ষম হয়েছি যা কোনও উপাদানটির জীবনচক্রের উপর নির্ভর করে। এই সামান্য উদাহরণটি $rootScopeইভেন্ট শ্রোতার রেজিস্ট্রেশন এবং নিবন্ধন করতে দেখায় $on। যখন জেনে গিয়েছে যে নিয়ন্ত্রক দৃশ্যে তার উল্লেখটি হারিয়ে ফেললে বা ধ্বংস হয়ে যায় তখন এটিকে আবদ্ধ করা কোনও ইভেন্টটিকে আনন্ডিন $onকরা $rootScopeযাবে না আমাদের $rootScope.$onম্যানুয়ালি শ্রোতাদের ধ্বংস করতে হবে । সেই $onDestroyজিনিসটি রাখার জন্য একটি ভাল জায়গা হ'ল একটি উপাদানটির জীবনচক্র ফাংশন:

var myApp = angular.module('myApp',[]);

myApp.controller('MyCtrl', function ($scope, $rootScope) {

  var registerScope = null;

  this.$onInit = function () {
    //register rootScope event
    registerScope = $rootScope.$on('someEvent', function(event) {
        console.log("fired");
    });
  }

  this.$onDestroy = function () {
    //unregister rootScope event by calling the return function
    registerScope();
  }
});

>> ফিডাল ডেমো


17

অথবা আপনি কেবল নিয়ামকটিতে ইনলাইনটি শুরু করতে পারেন। আপনি যদি নিয়ামকের অভ্যন্তরীণ কোনও ডিআইএন ফাংশন ব্যবহার করেন তবে এটিকে সুযোগের মধ্যে সংজ্ঞায়িত করার দরকার নেই। আসলে এটি নিজে সম্পাদনকারী হতে পারে:

function MyCtrl($scope) {
    $scope.isSaving = false;

    (function() {  // init
        if (true) { // $routeParams.Id) {
            //get an existing object
        } else {
            //create a new object
        }
    })()

    $scope.isClean = function () {
       return $scope.hasChanges() && !$scope.isSaving;
    }

    $scope.hasChanges = function() { return false }
}

4
কোনও কারণ আছে যে ডিআইডি কোড বেনামে বন্ধ রয়েছে?
অ্যাডাম টলি

@ অ্যাডাম টোলি এর কোন বিশেষ কারণ নেই। তিনি কেবল কোনও ফাংশন সংজ্ঞায়িত করেন এবং তত্ক্ষণাত এটিকে কোনও ভারে আবদ্ধ না করে কল করেন।
তাইয়ার

7
আপনি ব্যক্তিগত ইউনিট () টি এইভাবে সঠিকভাবে ফাংশনটি পরীক্ষা করতে পারেন?
স্টিভেন রজার্স

শুধুমাত্র পাবলিক সদস্যদের ইউনিট পরীক্ষা করা হয়। ইউনিট পরীক্ষাগুলি প্রত্যাশিত ফলাফল পাওয়ার জন্য ক্লাসগুলি ব্যক্তিগতভাবে কী করে তার উপর নির্ভর করা উচিত নয়।
ফিল

14

আমি আমার প্রকল্পগুলিতে নিম্নলিখিত টেম্পলেটটি ব্যবহার করি:

angular.module("AppName.moduleName", [])

/**
 * @ngdoc controller
 * @name  AppName.moduleName:ControllerNameController
 * @description Describe what the controller is responsible for.
 **/
    .controller("ControllerNameController", function (dependencies) {

        /* type */ $scope.modelName = null;
        /* type */ $scope.modelName.modelProperty1 = null;
        /* type */ $scope.modelName.modelPropertyX = null;

        /* type */ var privateVariable1 = null;
        /* type */ var privateVariableX = null;

        (function init() {
            // load data, init scope, etc.
        })();

        $scope.modelName.publicFunction1 = function () /* -> type  */ {
            // ...
        };

        $scope.modelName.publicFunctionX = function () /* -> type  */ {
            // ...
        };

        function privateFunction1() /* -> type  */ {
            // ...
        }

        function privateFunctionX() /* -> type  */ {
            // ...
        }

    });

এটি দেখতে দেখতে পরিষ্কার দেখাচ্ছে, তবে iffe আপনাকে সেই সুযোগগুলি চালিয়ে যাওয়া থেকে বিরত রাখে যা আপনি স্কোপটিতে সংজ্ঞা দিচ্ছেন যা আমাদের প্রায়শই যা করা দরকার তা একবার শুরুতে চালনা করুন এবং তারপরে এগুলি চালাতে সক্ষম হওয়ার সুযোগও রয়েছে them আবার ব্যবহারকারীর প্রয়োজন অনুসারে
ক্রিসমার্ক

এটি, যদি এটি
নিয়ামকের
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.