AngularJS - একটি নির্দেশিকা তৈরি করুন যা এনজি-মডেল ব্যবহার করে


294

আমি এমন একটি ডিরেক্টরি তৈরি করার চেষ্টা করছি যা সেই উপাদান হিসাবে একই এনজি-মডেল দিয়ে একটি ইনপুট ক্ষেত্র তৈরি করবে যা নির্দেশকে তৈরি করে।

আমি এতদূর যা নিয়ে এলাম তা এখানে:

এইচটিএমএল

<!doctype html>
<html ng-app="plunker" >
<head>
  <meta charset="utf-8">
  <title>AngularJS Plunker</title>
  <link rel="stylesheet" href="style.css">
  <script>document.write("<base href=\"" + document.location + "\" />");</script>
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
  <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.2/angular.js"></script>
  <script src="app.js"></script>
</head>
<body ng-controller="MainCtrl">
  This scope value <input ng-model="name">
  <my-directive ng-model="name"></my-directive>
</body>
</html>

জাভাস্ক্রিপ্ট

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

app.controller('MainCtrl', function($scope) {
  $scope.name = "Felipe";
});

app.directive('myDirective', function($compile) {
  return {
    restrict: 'E',
    scope: {
      ngModel: '='
    },
    template: '<div class="some"><label for="{{id}}">{{label}}</label>' +
      '<input id="{{id}}" ng-model="value"></div>',
    replace: true,
    require: 'ngModel',
    link: function($scope, elem, attr, ctrl) {
      $scope.label = attr.ngModel;
      $scope.id = attr.ngModel;
      console.debug(attr.ngModel);
      console.debug($scope.$parent.$eval(attr.ngModel));
      var textField = $('input', elem).
        attr('ng-model', attr.ngModel).
        val($scope.$parent.$eval(attr.ngModel));

      $compile(textField)($scope.$parent);
    }
  };
});

যাইহোক, আমি নিশ্চিত না যে এই পরিস্থিতিটি হ্যান্ডেল করার সঠিক উপায়, এবং একটি ত্রুটি রয়েছে যে এনজি-মডেল লক্ষ্য ক্ষেত্রের মান দিয়ে আমার নিয়ন্ত্রণ আরম্ভ করা হচ্ছে না।

উপরের কোডটির একটি প্লঙ্কার এখানে রয়েছে: http://plnkr.co/edit/IvrDbJ

এটি পরিচালনা করার সঠিক উপায় কী?

সম্পাদনা : ng-model="value"টেমপ্লেট থেকে অপসারণ করার পরে , এটি ঠিকঠাক কাজ করছে বলে মনে হচ্ছে। তবে, আমি এই প্রশ্নটি উন্মুক্ত রাখব কারণ আমি ডাবল চেক করতে চাই এটি করার এই সঠিক উপায়।


1
আপনি যদি scopeএটি সরিয়ে সেট করেন তবে কী হবে scope: false? কিভাবে ng-modelএই ক্ষেত্রে আবদ্ধ ?
সাইদ নেমতি

উত্তর:


210

সম্পাদনা : এই উত্তরটি পুরানো এবং সম্ভবত পুরানো। কেবল একটি মাথা আপ যাতে এটি লোককে বিপথগামী করে না। আমি আর অ্যাঙ্গুলার ব্যবহার করি না তাই আমি উন্নতি করার পক্ষে ভাল অবস্থানে নেই।


এটি আসলে বেশ ভাল যুক্তিযুক্ত তবে আপনি কিছুটা সহজ করতে পারেন।

নির্দেশিকা

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

app.controller('MainCtrl', function($scope) {
  $scope.model = { name: 'World' };
  $scope.name = "Felipe";
});

app.directive('myDirective', function($compile) {
  return {
    restrict: 'AE', //attribute or element
    scope: {
      myDirectiveVar: '=',
     //bindAttr: '='
    },
    template: '<div class="some">' +
      '<input ng-model="myDirectiveVar"></div>',
    replace: true,
    //require: 'ngModel',
    link: function($scope, elem, attr, ctrl) {
      console.debug($scope);
      //var textField = $('input', elem).attr('ng-model', 'myDirectiveVar');
      // $compile(textField)($scope.$parent);
    }
  };
});

নির্দেশ সহ এইচটিএমএল

<body ng-controller="MainCtrl">
  This scope value <input ng-model="name">
  <my-directive my-directive-var="name"></my-directive>
</body>

সিএসএস

.some {
  border: 1px solid #cacaca;
  padding: 10px;
}

আপনি এই প্লঙ্কারের সাথে ক্রিয়াতে এটি দেখতে পাচ্ছেন

আমি যা দেখছি তা এখানে:

  • আপনি কেন 'এনজি-মডেল' ব্যবহার করতে চান তা আমি বুঝতে পেরেছি তবে আপনার ক্ষেত্রে এটি প্রয়োজনীয় নয়। এনজি-মডেল হ'ল সুযোগের সাথে বিদ্যমান এইচটিএমএল উপাদানগুলিকে লিঙ্ক করা । যেহেতু আপনি নিজেই একটি নির্দেশিকা তৈরি করছেন আপনি একটি 'নতুন' এইচটিএমএল উপাদান তৈরি করছেন, সুতরাং আপনার এনজি-মডেলের প্রয়োজন হবে না।

সম্পাদনা যেমন মার্ক তার মন্তব্যে উল্লেখ করেছেন , কেবল কনভেনশন রাখার জন্য আপনি এনজি-মডেল ব্যবহার করতে পারবেন না এমন কোনও কারণ নেই ।

  • আপনার নির্দেশে স্পষ্টভাবে একটি সুযোগ তৈরি করে (একটি 'বিচ্ছিন্ন' সুযোগ), নির্দেশকের সুযোগটি পিতামাতার স্কোপে 'নাম' ভেরিয়েবল অ্যাক্সেস করতে পারে না (যার কারণে আমি মনে করি আপনি এনজি-মডেলটি ব্যবহার করতে চেয়েছিলেন)।
  • আমি আপনার নির্দেশনা থেকে এনজিমডেল সরিয়েছি এবং এটিকে একটি কাস্টম নাম দিয়ে প্রতিস্থাপন করেছি যা আপনি যে কোনও কিছুতে পরিবর্তন করতে পারবেন।
  • যে জিনিসটি এটি এখনও সমস্ত কাজ করে তা হ'ল সুযোগে '=' সাইন। 'স্কোপ' শিরোনামের অধীনে ডক্স ডক্স চেকআউট করুন ।

সাধারণভাবে, আপনার নির্দেশাবলীর বিচ্ছিন্ন সুযোগ ব্যবহার করা উচিত (যা আপনি সঠিকভাবে করেছেন) এবং '=' টাইপ স্কোপটি ব্যবহার করা উচিত যদি আপনি আপনার নির্দেশের মধ্যে কোনও মান চান সর্বদা পিতামাতার স্কোপের কোনও মান মানচিত্রের জন্য।


18
+1, তবে আমি নিশ্চিত নই যে "এনজি-মডেল হ'ল এইচটিএমএল উপাদানগুলিকে স্কোপের একটি মান সহ লিঙ্ক করা" এই উক্তিটির সাথে আমি একমত নই contenteditableকৌণিক দস্তাবেজের দুটি নির্দেশিক উদাহরণ - ফর্ম পৃষ্ঠা , এনজিডেলকন্ট্রোলার পৃষ্ঠা - উভয়ই এনজি-মডেল ব্যবহার করে। এবং এনজিএমডেল কনট্রোলার পৃষ্ঠাটি বলে যে এই নিয়ামকটি "অন্য নির্দেশাবলীর দ্বারা প্রসারিত করার জন্য বোঝানো হয়েছিল।"
রাজকক

33
আমি নিশ্চিত নই কেন এই উত্তরটিকে এত বেশি রেট দেওয়া হয়েছে কেননা এটি মূল প্রশ্নটি যা জিজ্ঞাসা করেছিল তা পূরণ করে না - যা এনজিমোডেল ব্যবহার করতে হয়। হ্যাঁ, প্যারেন্ট কন্ট্রোলারে স্টেট রেখে এনজিমোডেল ব্যবহার করা এড়াতে পারে তবে দুটি নিয়ামককে শক্ত করে আবদ্ধ করা এবং সেগুলি স্বাধীনভাবে ব্যবহার / পুনরায় ব্যবহার করতে সক্ষম না হওয়া ব্যয় করে। এটি দুটি উপাদানগুলির মধ্যে শ্রোতা স্থাপনের পরিবর্তে বৈশ্বিক পরিবর্তনশীল ব্যবহার করার মতো - এটি প্রযুক্তিগতভাবে সহজ হতে পারে তবে বেশিরভাগ ক্ষেত্রে এটি কোনও ভাল সমাধান নয়।
প্যাট নেইমায়ার

আমি যুক্ত করব যে তিনি যদি পিতা বা মাতা নিয়ন্ত্রকের উপর নির্ভর করতে চান তবে তার এটি 'প্রয়োজনীয়: ^ পিতা বা মাতা' দিয়ে ইনজেকশন করা উচিত - যাতে তিনি নির্ভরতাটিকে সুস্পষ্ট এবং পছন্দসইভাবে পছন্দসই করতে পারেন।
প্যাট নেইমায়ার

3
@ জিরোইন আমি যেভাবে দেখছি তার প্রধান সুবিধাটি হ'ল অন্যান্য জায়গাগুলির সাথে সামঞ্জস্যতা যেখানে মডেলটি পাস হয়েছে hg-model(এবং সংযুক্তির বিষয়টি নয়, আইএমও)। এইভাবে ডেটা প্রসঙ্গটি সর্বদা এনজি-মডেল ব্যবহার করে তা এটি <input>কোনও কাস্টম নির্দেশ হোক না কেন এইচটিএমএল লেখকের জন্য জ্ঞানীয় ওভারহেডকে সহজ করে তুলবে। অর্থাৎ এটি প্রতিটি লেখার জন্য নামটি কী তা খুঁজে বের করার জন্য এইচটিএমএল লেখককে সংরক্ষণ করে my-directive-var, বিশেষত যেহেতু আপনাকে সহায়তার জন্য কোনও স্ব-অসম্পূর্ণতা নেই।
জাই চ্যাং

2
উম্ম ... ঠিক আছে ... তবে এখন এটি আর ng-model-optionsকোনও এনজি মডেলের জিনিস নিয়ে কাজ করে না, তাই না?
জর্জ মাউয়ার

68

আমি সমস্ত উত্তরের কম্বো নিয়েছি এবং এখন এনজি-মডেল বৈশিষ্ট্যের সাথে এটি করার দুটি উপায় রয়েছে:

  • একটি নতুন স্কোপ যা এনজিএমডেল অনুলিপি করে
  • একই সুযোগে যা লিঙ্কে একটি সংকলন করে

আমি নিশ্চিত নই যে আমি লিঙ্কের সময়ে সংকলন পছন্দ করি। তবে, আপনি যদি কেবলমাত্র উপাদানটিকে অন্যটির সাথে প্রতিস্থাপন করছেন তবে আপনার এটি করার দরকার নেই।

সব মিলিয়ে আমি প্রথমটিকে পছন্দ করি। কেবলমাত্র এতে স্কোপ {ngModel:"="}সেট করুন ng-model="ngModel"এবং আপনার টেম্পলেটে আপনি এটি কোথায় চান তা সেট করুন।

আপডেট : আমি কোড স্নিপেটটি ইনলাইন করেছিলাম এবং এঙ্গুলার ভি 1.2-এর জন্য আপডেট করেছি। দেখা যাচ্ছে যে বিচ্ছিন্ন সুযোগটি এখনও সেরা, বিশেষত যখন jQuery ব্যবহার না করা হয়। সুতরাং এটি নিচে ফোটে:

  • আপনি কি একটি একক উপাদান প্রতিস্থাপন করছেন: কেবল এটি প্রতিস্থাপন করুন, সুযোগটি একা রেখে দিন, তবে নোট করুন যে প্রতিস্থাপনটি v2.0 এর জন্য অবচিত হয়েছে:

    app.directive('myReplacedDirective', function($compile) {
      return {
        restrict: 'E',
        template: '<input class="some">',
        replace: true
      };
    });
  • অন্যথায় এটি ব্যবহার করুন:

    app.directive('myDirectiveWithScope', function() {
      return {
        restrict: 'E',
        scope: {
          ngModel: '=',
        },
        template: '<div class="some"><input ng-model="ngModel"></div>'
      };
    });

1
আমি তিনটি সুযোগ সম্ভাবনার সাথে এবং টেমপ্লেটের শিশু উপাদান বা টেমপ্লেটের মূল উপাদানগুলির জন্য প্লাঙ্কার আপডেট করেছি।
w00t

1
এটি দুর্দান্ত, তবে আপনি কীভাবে মূলত এই optionচ্ছিক করবেন? আমি একটি ইউআই লাইব্রেরির জন্য একটি পাঠ্যবক্সের নির্দেশনা তৈরি করছি, এবং আমি চাই মডেলটি alচ্ছিক হোক, মানে এনজিএমডেলটি সেট না করা থাকলে পাঠ্যবক্সটি এখনও কাজ করবে।
নিক র‌্যাডফোর্ড

1
@ নিকর্যাডফোর্ড সহজভাবে পরীক্ষা করুন যে এনজিমোডেলটি $ স্কোপে সংজ্ঞায়িত করা হয়েছে এবং যদি না, এটি ব্যবহার করবেন না?
w00t

1
ng-modelবিচ্ছিন্ন সুযোগে পুনরায় ব্যবহার করার সাথে কি কোনও সমস্যা বা অতিরিক্ত ওভারহেড থাকবে ?
জেফ লিং

2
@ জ্যাফলিং নিশ্চিত নয় তবে আমি এটি মনে করি না। এনজিওমোডেল অনুলিপি করা বেশ হালকা ওজন এবং বিচ্ছিন্ন স্কোপ সীমাবদ্ধতার এক্সপোজার।
w00t

52

এটি এত জটিল নয়: আপনার ডারেক্টিভের ক্ষেত্রে, একটি নাম ব্যবহার করুন: scope:{alias:'=ngModel'}

.directive('dateselect', function () {
return {
    restrict: 'E',
    transclude: true,
    scope:{
        bindModel:'=ngModel'
    },
    template:'<input ng-model="bindModel"/>'
}

আপনার এইচটিএমএল এ, স্বাভাবিক হিসাবে ব্যবহার করুন

<dateselect ng-model="birthday"></dateselect>

1
কেন্ডো ইউআইয়ের মতো লাইব্রেরিগুলির সাথে ডিল করার সময় এটি এত সহজ। ধন্যবাদ!
বাইটবেন্ডার

30

আপনার যখন কেবলমাত্র মডেলটির need ভিউভ্যালু বা $ মডেলভ্যালু অ্যাক্সেস করতে হবে তখনই আপনাকে এনজি-মডেল প্রয়োজন। এনজিএমডেলকন্ট্রোলার দেখুন । এবং এই ক্ষেত্রে, আপনি ব্যবহার করতে হবে require: '^ngModel'

বাকিগুলির জন্য, রয়ের উত্তর দেখুন


2
আপনার যদি $ ভিউভ্যালু বা $ মডেলওয়ালুর প্রয়োজন না হয় তবে এনজি-মডেলটিও দরকারী। আপনি কেবল @ কলির উদাহরণের মতো এনজি-মডেলের ডেটা-বাঁধাই করা বৈশিষ্ট্যগুলি চাইলেও এটি কার্যকর।
মার্ক রাজকক

1
আর ^সেখানে উচিত শুধুমাত্র যদি NG মডেল একটি পিতা বা মাতা উপাদান প্রয়োগ করা হয়
georgiosd

18

এটি একটি সামান্য দেরিতে উত্তরের, কিন্তু আমি এই ভয়ঙ্কর পাওয়া পোস্ট সম্পর্কে NgModelController, যা আমি মনে করি আপনি যা খুঁজছেন ঠিক হয়েছিল।

টিএল; ডিআর - আপনি ব্যবহার করতে পারেন require: 'ngModel'এবং তারপরে NgModelControllerআপনার লিঙ্কিং ফাংশনে যুক্ত করতে পারেন :

link: function(scope, iElement, iAttrs, ngModelCtrl) {
  //TODO
}

এইভাবে, কোনও হ্যাকের প্রয়োজন নেই - আপনি অ্যাংুলার অন্তর্নির্মিত ব্যবহার করছেন ng-model


2

আমি কোনও গুগলের মাধ্যমে এনজিএমডেল সেট করব না, আপনি এটি ঠিক টেমপ্লেটে উল্লেখ করতে পারেন:

template: '<div class="some"><label>{{label}}</label><input data-ng-model="ngModel"></div>',

প্লাঙ্কার : http://plnkr.co/edit/9vtmnw?p= পূর্বরূপ দেখুন


0

কৌণিক 1.5 থেকে কম্পোনেন্টগুলি ব্যবহার করা সম্ভব। উপাদানগুলি হ'ল যেতে-যাওয়া এবং এই সমস্যাটিকে সহজে সমাধান করে।

<myComponent data-ng-model="$ctrl.result"></myComponent>

app.component("myComponent", {
    templateUrl: "yourTemplate.html",
    controller: YourController,
    bindings: {
        ngModel: "="
    }
});

আপনার কন্ট্রোলারের অভ্যন্তরে আপনাকে যা করতে হবে তা হ'ল:

this.ngModel = "x"; //$scope.$apply("$ctrl.ngModel"); if needed

আমি যা পেয়েছি তা হ'ল এটি যদি কাজ করে তবে আপনি "<" এর পরিবর্তে "=" ব্যবহার করেন যা উপাদানগুলি ব্যবহার করে অন্যথায় সেরা অনুশীলন। আমি নিশ্চিত নই যে এই উত্তরের "আপনার কন্ট্রোলারটির ভিতরে" অংশটির অর্থ কী, এর বিন্দুটি উপাদানটির ভিতরে এনজিএমডেল সেট না করে?
মার্ক স্টোবার

1
@ মার্কস্টোবার "আপনার কন্ট্রোলারের ভিতরে" দিয়ে আমি কেবল এটিই দেখাতে চেয়েছিলাম যে এনজিমোডেল গেটর এবং সেটার হিসাবে উপলব্ধ। এই উদাহরণে $ ctrl.result "x" হয়ে যাবে।
নীলস স্টেইনবাইক

ঠিক আছে. আমার মনে হয় যে অন্যান্য অংশটি গুরুত্বপূর্ণ তা input ng-model="$ctrl.ngModel"হ'ল আপনিও করতে পারেন আপনার নিয়ামক টেম্পলেটটিতে এবং এটি tr ctrl.result এর সাথেও সিঙ্ক হবে।
মার্ক স্টোবার

0

বিচ্ছিন্ন সুযোগ তৈরি অনাকাঙ্ক্ষিত। আমি স্কোপ অ্যাট্রিবিউটটি ব্যবহার করা এড়িয়ে চলতাম এবং এরকম কিছু করব। সুযোগ: সত্য আপনাকে নতুন সন্তানের সুযোগ দেয় তবে আলাদা নয় not তারপরে পার্স ব্যবহার করুন স্থানীয় এনজোমোডেল অ্যাট্রিবিউটকে সরবরাহ করা একই বস্তুর জন্য স্থানীয় স্কোপ ভেরিয়েবলটি চিহ্নিত করতে।

app.directive('myDir', ['$parse', function ($parse) {
    return {
        restrict: 'EA',
        scope: true,
        link: function (scope, elem, attrs) {
            if(!attrs.ngModel) {return;}
            var model = $parse(attrs.ngModel);
            scope.model = model(scope);
        }
    };
}]);
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.