Angularjs: 'সিনট্যাক্স হিসাবে নিয়ামক' এবং $ ঘড়ি


153

controller asসিনট্যাক্স ব্যবহার করার সময় কীভাবে সম্পত্তি পরিবর্তনে সাবস্ক্রাইব করবেন ?

controller('TestCtrl', function ($scope) {
  this.name = 'Max';
  this.changeName = function () {
    this.name = new Date();
  }
  // not working       
  $scope.$watch("name",function(value){
    console.log(value)
  });
});
<div ng-controller="TestCtrl as test">
  <input type="text" ng-model="test.name" />
  <a ng-click="test.changeName()" href="#">Change Name</a>
</div>  

এই সম্পর্কে কি? $ ওয়াচ ()? এটি বৈধ: এটি $ ঘড়ি ('নাম', ...)
জোওও পোলো

উত্তর:


160

কেবল প্রাসঙ্গিক প্রসঙ্গে বাঁধুন।

$scope.$watch(angular.bind(this, function () {
  return this.name;
}), function (newVal) {
  console.log('Name changed to ' + newVal);
});

উদাহরণ: http://jsbin.com/yinadoce/1/edit

হালনাগাদ:

বোগদান গেরাসকের উত্তর আসলে এক ধরণের সমতুল্য, উভয় উত্তরই thisসঠিক প্রসঙ্গের সাথে আবদ্ধ করার চেষ্টা করে। তবে আমি তার উত্তর পরিষ্কার পেয়েছি er

এটি বলার পরে, প্রথম এবং সর্বাগ্রে, আপনাকে এর পিছনের অন্তর্নিহিত ধারণাটি বুঝতে হবে

আপডেট 2:

যারা ES6 ব্যবহার করেন তাদের জন্য, arrow functionআপনি সঠিক প্রসঙ্গে OOTB সহ একটি ফাংশন পান।

$scope.$watch(() => this.name, function (newVal) {
  console.log('Name changed to ' + newVal);
});

উদাহরণ


9
এই এবং $ সুযোগের মিশ্রণ এড়াতে আমরা কী এটিকে $ সুযোগ ছাড়াই ব্যবহার করতে পারি?
মিরন

4
আমি জানি না, তবে এটি পুরোপুরি ঠিক আছে। $scopeআপনার জন্য এক ধরণের পরিষেবা যা এই ধরণের পদ্ধতি সরবরাহ করে।
রায় মিলোহ

আপনি শোধন করা সম্ভব কি না namereturn this.name;নিয়ামক বা সম্পত্তি "নামে উল্লেখ করে name" এখানে?
জান্নিক জোখেম

3
@ জ্যানিক angular.bindএকটি সীমানা প্রসঙ্গে একটি ফাংশন প্রদান করে (আর্গ # 1)। আমাদের ক্ষেত্রে, আমরা বাঁধাই this, যা নিয়ন্ত্রণকারীর উদাহরণ, ফাংশনটির (আর্গ # 2) এর সাথে আবদ্ধ করি , তাই নিয়ামকের উদাহরণটির this.nameসম্পত্তি বোঝায় name
রায় মিলোহ

আমি মনে করি আমি ঠিক বুঝতে পেরেছি এটি কীভাবে কাজ করে। যখন সীমাবদ্ধ ফাংশন বলা হয়, এটি কেবল দেখা মানটির মূল্যায়ন করে, তাই না?
জান্নিক জোখেম 21

138

আমি সাধারণত এটি করি:

controller('TestCtrl', function ($scope) {
    var self = this;

    this.name = 'Max';
    this.changeName = function () {
        this.name = new Date();
   }

   $scope.$watch(function () {
       return self.name;
   },function(value){
        console.log(value)
   });
});

3
আমি সম্মত হই যে এটিই সেরা উত্তর, যদিও আমি যুক্ত করব যে এটি নিয়ে বিভ্রান্তি সম্ভবত প্রথম যুক্তি হিসাবে কোনও ফাংশনটি পাস করার $scope.$watchএবং সেই ফাংশনটি ক্লোজর থেকে কোনও মান ফিরিয়ে দেওয়ার জন্য ব্যবহার করার উপর রয়েছে। আমি এর অন্য একটি উদাহরণ জুড়ে এখনও চালাতে পারি, তবে এটি কার্যকর হয় এবং সেরা। আমি নীচে উত্তরটি বেছে না নেওয়ার কারণ (অর্থাত্‍ $scope.$watch('test.name', function (value) {});) কারণ এটির প্রয়োজন ছিল যে আমি আমার টেমপ্লেটে বা ui.router- এর P রাষ্ট্রপ্রযোজক এবং আমার কোনও নিয়মকে অজান্তেই অবধি ভেঙে ফেলতে চাইলে আমার কন্ট্রোলারের নামটি কি হার্ড-কোডের প্রয়োজন।
মরিস সিঙ্গার

এছাড়াও, এই উত্তর এবং বর্তমানে স্বীকৃত উত্তরের (যা ব্যবহার করে angular.bind) মধ্যে একমাত্র মূল পার্থক্য হ'ল আপনি বন্ধের মধ্যে আবদ্ধ হতে thisবা কেবল অন্য কোনও রেফারেন্স যুক্ত করতে চান কিনা this। এগুলি কার্যত সমতুল্য, এবং আমার অভিজ্ঞতা অনুসারে এই ধরণের পছন্দ প্রায়শই একটি বিষয়গত আহ্বান এবং খুব দৃ strong় মতামতের বিষয়টি।
মরিস সিঙ্গার

1
ES6 সম্পর্কে একটি দুর্দান্ত জিনিস হ'ল সঠিক জেএস সুযোগ পাওয়ার জন্য 2 টি পূর্বোক্ত ওয়ার্কআরউন্ডগুলি করা বাদ দেওয়া হবে । $scope.$watch( ()=> { return this.name' }, function(){} ) উদ্ধার করার জন্য
চর্বিযুক্ত

1
আপনি ঠিক করতে পারেন() => this.name
coblr

আপনি কি এই কাজটি তৈরি করে $scope.$watchCollectionএখনও oldVal, newValপ্যারামগুলি পেতে পারেন ?
ক্র্যাকেন

23

তুমি ব্যবহার করতে পার:

   $scope.$watch("test.name",function(value){
        console.log(value)
   });

এটি আপনার উদাহরণ সহ জেএসফিডেল কাজ করছে ।


25
এই পদ্ধতির সমস্যাটি হ'ল জেএস এখন এইচটিএমএল এর উপর নির্ভর করে $ কাজটি দেখার জন্য নিয়ামককে সর্বত্র একই নামে আবদ্ধ হতে বাধ্য (এই ক্ষেত্রে "পরীক্ষা") বাধ্য করে। সূক্ষ্ম বাগগুলি প্রবর্তন করা খুব সহজ হবে।
jsdw

যদি আপনি কৌনিক 2 এর মতো কৌনিক 1 লিখছেন যেখানে সবকিছুই দিকনির্দেশক তবে এটি আশ্চর্যজনকভাবে কাজ করে। যদিও এখনই অবজেক্ট.ওবিজারটি আশ্চর্যজনক হবে।
ল্যাংডন

13

"টেস্টটিআরসিটিএল হিসাবে পরীক্ষা হিসাবে" "পরীক্ষা" ব্যবহার করার অনুরূপ, অন্য উত্তরে বর্ণিত হিসাবে, আপনি "স্ব" কে আপনার সুযোগ প্রদান করতে পারেন:

controller('TestCtrl', function($scope){
    var self = this;
    $scope.self = self;

    self.name = 'max';
    self.changeName = function(){
            self.name = new Date();
        }

    $scope.$watch("self.name",function(value){
            console.log(value)
        });
})

এইভাবে, আপনি ডিওএম ("টেস্ট হিসাবে টেস্টসিটিএল হিসাবে টেস্ট") নির্দিষ্ট করা নামের সাথে আবদ্ধ নন এবং আপনি কোনও ফাংশনে .bind (এটি) বাঁধার প্রয়োজনীয়তাও এড়াচ্ছেন।

... নির্দিষ্ট মূল HTML ব্যবহারের জন্য:

<div ng-controller="TestCtrl as test">
    <input type="text" ng-model="test.name" />
    <a ng-click="test.changeName()" href="#">Change Name</a>
</div>

কেবল একটি জিনিস জানতে চান, অর্থাত্ $scopeএকটি পরিষেবা, তাই আমরা যদি যোগ করি $scope.self = this, তবে অন্য নিয়ামকের মধ্যে যদি আমরা একই করি তবে সেখানে কী হবে?
বিবেক কুমার

12

AngularJs 1.5 নিয়ন্ত্রণকারীর কাঠামোর জন্য ডিফল্ট $ ctrl সমর্থন করে।

$scope.$watch("$ctrl.name", (value) => {
    console.log(value)
});

$ ওয়াচগ্রুপ ব্যবহার করার সময় আমার পক্ষে কাজ করে না, এটি কি জানা সীমা? আমি এই বৈশিষ্ট্যের একটি লিঙ্ক ভাগ করতে পারি কারণ আমি এটি সম্পর্কে কিছুই খুঁজে পাচ্ছি না।
ব্যবহারকারী 1852503

@ user1852503 দেখুন ডকস.আঙ্গুলারজস.আর / গাইড / কম্পোনেন্টের তুলনা সারণি নির্দেশক / উপাদান সংজ্ঞা এবং 'কন্ট্রোলার'স রেকর্ড পরীক্ষা করুন।
নীলস স্টেইনবিক

আমি এখন বুঝতে পেরেছি. আপনার উত্তরটি কিছুটা বিভ্রান্তিকর। সনাক্তকারী $ সিটিআরএল একটি বৈশিষ্ট্য হিসাবে নিয়ন্ত্রণকারীর সাথে সম্পর্কযুক্ত না (যেমন $ সূচকটি এনজি-রিপিট উদাহরণস্বরূপ করে) এটি কেবল কোনও উপাদানটির অভ্যন্তরে নিয়ামকের ডিফল্ট নাম হিসাবে ঘটে থাকে (এবং প্রশ্নটি এমনকি একটি সম্পর্কেও নয় উপাদান).
ব্যবহারকারী 1852503

@ user1852503 1) $ ctrl নিয়ামককে নিয়ন্ত্রণ করে (নিয়ন্ত্রণকারী হিসাবে) 2) প্রশ্নটি উপাদানগুলির সম্পর্কে, যেহেতু এটি উল্লেখ করেছে: "<div ng-controller =" TestCtrl as test ">" "" 3) এই পৃষ্ঠায় সমস্ত উত্তর একরকম আমার উত্তর হিসাবে একই। ৪) ডকুমেন্টেশন সম্পর্কিত $ ওয়াচগ্রুপটি $ ctrl.name ব্যবহার করার সময় ঠিকঠাক কাজ করা উচিত কারণ এটি $ ওয়াচের উপর ভিত্তি করে।
নীলস স্টেইনবিক

2

আপনি আসলে $ ওয়াচ () এর প্রথম যুক্তি হিসাবে কোনও ফাংশনে পাস করতে পারেন:

 app.controller('TestCtrl', function ($scope) {
 this.name = 'Max';

// hmmm, a function
 $scope.$watch(function () {}, function (value){ console.log(value) });
 });

যার অর্থ আমরা আমাদের এই নামটি উল্লেখটি ফিরিয়ে দিতে পারি:

app.controller('TestCtrl', function ($scope) {
    this.name = 'Max';

    // boom
    $scope.$watch(angular.bind(this, function () {
    return this.name; // `this` IS the `this` above!!
    }), function (value) {
      console.log(value);
    });
});

কন্ট্রোলার বিষয় সম্পর্কে একটি আকর্ষণীয় পোস্ট পড়ুন https://toddmotto.com/digging-into-angulars-controller-as-syntax/


1

আপনি ular onChanges কৌণিক উপাদান জীবনচক্র ব্যবহার করতে পারেন ।

এখানে ডকুমেন্টেশন দেখুন: উপাদান ভিত্তিক অ্যাপ্লিকেশন বিভাগের অধীনে https://docs.angularjs.org/guide/comp घटक


0

ES6 সিনট্যাক্সে একটি $ ঘড়ি লেখা আমার প্রত্যাশার মতো সহজ ছিল না। আপনি যা করতে পারেন তা এখানে:

// Assuming
// controllerAs: "ctrl"
// or
// ng-controller="MyCtrl as ctrl"
export class MyCtrl {
  constructor ($scope) {
    'ngInject';
    this.foo = 10;
    // Option 1
    $scope.$watch('ctrl.foo', this.watchChanges());
    // Option 2
    $scope.$watch(() => this.foo, this.watchChanges());
  }

  watchChanges() {
    return (newValue, oldValue) => {
      console.log('new', newValue);
    }
  }
}

-1

দ্রষ্টব্য : যখন ভিউ এবং কন্ট্রোলার কোনও রুটে বা নির্দেশমূলক সংজ্ঞা বস্তুর মাধ্যমে মিলিত হয় তখন এটি কাজ করে না। নীচে দেখানো বিষয়গুলি কেবল তখনই কাজ করে যখন এইচটিএমএলে "সামারকন্ট্রোলার হিসাবে সামসকন্ট্রোলার" থাকে। ঠিক যেমন মার্ক ভি। নীচের মন্তব্যে উল্লেখ করেছেন এবং যেমনটি তিনি বলেছেন যে বোগদান যেমন করেন তেমনি করাই ভাল।

আমি ব্যবহার করি: var vm = this;নিয়ন্ত্রকের শুরুতে "এই" শব্দটি আমার পথ থেকে সরিয়ে নিতে। তারপরে vm.name = 'Max';এবং ঘড়িতে আমি return vm.name। আমি "ভিএম" ব্যবহার করি ঠিক যেমন @ বোগদান "স্ব" ব্যবহার করে। এই ভ্যার, এটি "ভিএম" বা "স্ব" হওয়া প্রয়োজন যেহেতু "এটি" শব্দটি ফাংশনের অভ্যন্তরে আলাদা প্রসঙ্গটি গ্রহণ করে। (সুতরাং এই নামটি ফিরিয়ে দেওয়া কার্যকর হবে না) এবং হ্যাঁ, $ ঘড়িতে পৌঁছানোর জন্য আপনার নিজের "সুন্দর হিসাবে নিয়ন্ত্রক হিসাবে" সমাধানটি ইনজেক্ট করতে হবে। জন পাপের স্টাইল গাইড দেখুন: https://github.com/johnpapa/angularjs-styleguide# নিয়ন্ত্রণকারী

function SomeController($scope, $log) {
    var vm = this;
    vm.name = 'Max';

    $scope.$watch('vm.name', function(current, original) {
        $log.info('vm.name was %s', original);
        $log.info('vm.name is now %s', current);
    });
}

11
এটি আপনার HTML এ যতক্ষণ "" ভিএম হিসাবে সামসকন্ট্রোলার "রয়েছে ততক্ষণ কাজ করে। এটি বিভ্রান্তিকর, যদিও: ঘড়ির অভিব্যক্তির "vm.name" এর "var vm = this;" এর সাথে কোনও সম্পর্ক নেই। "নিয়ামক হিসাবে" এর সাথে ঘড়ি ব্যবহারের একমাত্র নিরাপদ উপায় হ'ল প্রথম যুক্তি হিসাবে কোনও ফাংশনটি পাস করা, যেমনটি বোগদান উপরে তুলে ধরেছেন।
মার্ক ভিজার 21

-1

এখানে আপনি কীভাবে $ সুযোগ (এবং $ ঘড়ি!) ছাড়াই এটি করেন শীর্ষস্থানীয় 5 ভুল - আপত্তিজনক ঘড়ি

আপনি যদি "নিয়ামক হিসাবে" সিনট্যাক্স ব্যবহার করেন তবে $ স্কোপ ব্যবহার এড়াতে এটি আরও ভাল এবং পরিষ্কার।

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

var app = angular.module('my-module', []);

app.factory('testService', function() {
    var name = 'Max';

    var getName = function() {
        return name;
    }

    var setName = function(val) {
        name = val;
    }

    return {getName:getName, setName:setName};
});

app.controller('TestCtrl', function (testService) {
    var vm = this;

    vm.changeName = function () {
        vm.name = new Date();
    }

    Object.defineProperty(this, "name", {
        enumerable: true,
        configurable: false,
        get: function() {
            return testService.getName();
        },
        set: function (val) {
            testService.setName(val);
            console.log(vm.name);
        }
    }); 
});

ফিডাল কাজ করছে না এবং এটি কোনও বস্তুর সম্পত্তি পর্যবেক্ষণ করবে না।
রুটিকাল ভি।

@RooticalV। ফিডল কাজ করছে। (নিশ্চিত হয়ে নিন যে আপনি যখন AngualrJS চালাচ্ছেন, আপনি লোডের ধরণটি এখন নর্যাপ-হেড / নওর্যাপ-বডি হিসাবে উল্লেখ করেছেন
বিনু জসিম

দুঃখিত তবে আমি এখনও এটি চালাতে সক্ষম হই নি, কারণ আপনার সমাধানটি খুব অন্তর্দৃষ্টিযুক্ত
হ্যাপি

@ খুশি নিশ্চিত করুন যে আপনি লাইব্রেরিটি কৌনিক 1.4 হিসাবে বেছে নিয়েছেন। (২.০ কাজ করবে কিনা তা আমি নিশ্চিত নই) এবং লোড টাইপ নো মোড়ক, এবং রান টিপুন। এটি কাজ করা উচিত.
বিনু জসিম
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.