অ্যাঙ্গুলারজেএস-এ বিচ্ছিন্ন সুযোগ ছাড়াই কোনও নির্দেশিকা থেকে একটি নিয়ামক ফাংশন কল করুন


95

আমি বিচ্ছিন্ন সুযোগ ব্যবহার না করে কোনও নির্দেশকের মধ্যে থেকে প্যারেন্ট স্কোপটিতে কোনও ফাংশন কল করার কোনও উপায় খুঁজে পাচ্ছি বলে মনে হচ্ছে না। আমি জানি যে আমি যদি বিচ্ছিন্ন সুযোগ ব্যবহার করি তবে আমি প্যারেন্ট স্কোপটিতে ফাংশনটি অ্যাক্সেস করতে কেবল বিচ্ছিন্নভাবে "&" ব্যবহার করতে পারি, তবে যখন বিচ্ছিন্ন সুযোগটি প্রয়োজন হয় না তখন তার পরিণতি হয়। নিম্নলিখিত এইচটিএমএল বিবেচনা করুন:

<button ng-hide="hideButton()" confirm="Are you sure?" confirm-action="doIt()">Do It</button>

এই সাধারণ উদাহরণে, আমি একটি জাভাস্ক্রিপ্ট কনফার্ম ডায়ালগ প্রদর্শন করতে চাই এবং নিশ্চিতকরণ ডায়ালগটিতে "ঠিক আছে" ক্লিক করুন তবে কেবল ডআইটি () কল করুন। এটি একটি বিচ্ছিন্ন সুযোগ ব্যবহার করে সহজ। দিকনির্দেশনাটি এর মতো দেখায়:

.directive('confirm', function () {
    return {
        restrict: 'A',
        scope: {
            confirm: '@',
            confirmAction: '&'
        },
        link: function (scope, element, attrs) {
            element.bind('click', function (e) {
                if (confirm(scope.confirm)) {
                    scope.confirmAction();
                }
            });
        }
    };
})

তবে সমস্যাটি হ'ল, কারণ আমি বিচ্ছিন্ন সুযোগ ব্যবহার করছি, উপরের উদাহরণে এনজি-হাইড প্যারেন্ট স্কোপের বিরুদ্ধে আর চালায় না , বরং বিচ্ছিন্ন সুযোগে (যেহেতু কোনও নির্দেশে বিচ্ছিন্ন স্কোপ ব্যবহার করার ফলে সেই উপাদানটির সমস্ত দিকনির্দেশিত হয়) বিচ্ছিন্ন সুযোগ ব্যবহার করুন)। এখানে উপরের উদাহরণের একটি জেএসফিডাল যেখানে এনজি- হিড কাজ করছে না। (নোট করুন যে এই ফিডলে আপনি যখন ইনপুট বাক্সে "হ্যাঁ" টাইপ করবেন তখন বোতামটি আড়াল করা উচিত))

বিকল্পটি কোনও বিচ্ছিন্ন সুযোগ ব্যবহার না করা , যা এই নির্দেশিকার সুযোগকে বিচ্ছিন্ন করার প্রয়োজন নেই বলেই আমি এখানে সত্যই চাই। আমার একটাই সমস্যা হ'ল আমি যদি কোনও ব্যবস্থাকে বিচ্ছিন্ন সুযোগে না দিয়ে পারি তবে প্যারেন্ট স্কোপটিতে আমি কীভাবে কল করব ?

এখানে একটি জিসফিল রয়েছে যেখানে আমি বিচ্ছিন্ন সুযোগ ব্যবহার করছি না এবং এনজি-হাইড ভাল কাজ করছে, তবে অবশ্যই, কনফার্মেশন করার কলটি () কাজ করে না, এবং আমি কীভাবে এটি কাজ করব তা জানি না।

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

বিকল্পভাবে, আমি যদি অন্য নির্দেশাবলী পিতামাতার সুযোগের বিরুদ্ধে কাজ করে তবে একটি বিচ্ছিন্ন সুযোগ ব্যবহার করে এমন সমাধানগুলি শুনতে আগ্রহী হব , তবে আমি মনে করি এটি সম্ভব নয়।


অতিক্রম তাদের জন্য, ড্যান Wahlin বিছিন্ন সুযোগ এবং ফাংশন পরামিতি ব্যাখ্যা একটি খুব ভাল নিবন্ধ লেখা হয়েছে: weblogs.asp.net/dwahlin/...
tanguy_k

উত্তর:


118

যেহেতু নির্দেশটি কেবল একটি ফাংশনকে কল করছে (এবং কোনও সম্পত্তির উপর কোনও মূল্য নির্ধারণের চেষ্টা করছে না), তাই আপনি $ পার্সের পরিবর্তে (বিচ্ছিন্ন স্কোপ সহ) $ eval ব্যবহার করতে পারেন :

scope.$apply(function() {
    scope.$eval(attrs.confirmAction);
});

বা আরও ভাল, কেবলমাত্র $ প্রয়োগ করুন , যা স্কোপের বিপরীতে তার যুক্তিটি প্রকাশ করবে ate

scope.$apply(attrs.confirmAction);

ফিডল


যে জানতাম না, তার জন্য ধন্যবাদ। আমি সর্বদা ভেবেছিলাম পার্স পদ্ধতিটি খুব বেশি শব্দযুক্ত।
ক্লার্ক প্যান

4
আপনি কিভাবে এই ফাংশন পরামিতি সেট করবেন?
সিএমসিডিগ্রাগনকাই

4
@ সিএমসিডিগ্রাগনকাই, যদি ফাংশনে আর্গুমেন্ট থাকে তবে আপনি সেগুলি এইচটিএমএলে নির্দিষ্ট করতে পারেন confirm-action="doIt(arg1)", এবং তারপরে scope.arg1calling ইভাল কল করার আগে সেট করতে পারেন । : যাইহোক, এটা সম্ভবত ব্যবহার $ পার্স ক্লিনার হবে stackoverflow.com/a/16200618/215945
মার্ক Rajcok

স্কোপ করা কি সম্ভব নয়? Al eval (attrs.doIt ({arg1: 'blah'}) ;?
CMCDragonkai

4
@CMCDragonkai, না, scope.$eval(attrs.confirmAction({arg1: 'blah'})কাজ করবে না। আপনাকে সেই সিনট্যাক্সের সাথে পার্স করতে হবে।
রাজকক

17

আপনি AngularJS এ পার্স পরিষেবাটি ব্যবহার করতে চান।

সুতরাং আপনার উদাহরণের জন্য:

.directive('confirm', function ($parse) {
    return {
        restrict: 'A',

        // Child scope, not isolated
        scope : true,
        link: function (scope, element, attrs) {
            element.bind('click', function (e) {
                if (confirm(attrs.confirm)) {
                    scope.$apply(function(){

                        // $parse returns a getter function to be 
                        // executed against an object
                        var fn = $parse(attrs.confirmAction);

                        // In our case, we want to execute the statement in 
                        // confirmAction i.e. 'doIt()' against the scope 
                        // which this directive is bound to, because the 
                        // scope is a child scope, not an isolated scope. 
                        // The prototypical inheritance of scopes will mean 
                        // that it will eventually find a 'doIt' function 
                        // bound against a parent's scope.
                        fn(scope, {$event : e});
                    });
                }
            });
        }
    };
});

পার্স using পার্স ব্যবহার করে কোনও সম্পত্তি নির্ধারণের জন্য কিছু করার দরকার আছে, আপনি যখন আসবেন তখন আমি আপনাকে সেতুটি পার করব।


ধন্যবাদ, ক্লার্ক, আমি ঠিক তাই খুঁজছিলাম আমি $ পার্স ব্যবহার করার চেষ্টা করেছি, কিন্তু সুযোগটি পাস করতে ব্যর্থ হলাম এটি আমার পক্ষে কাজ করছে না। এটি নিখুঁত।
জিম কুপার

আমি অবাক হয়ে জানতে পারি যে এই সমাধানটিও সুযোগ ছাড়াই কাজ করে: সত্য। আমার বোধগম্যতা ছিল সেই সুযোগটি: সত্যটিই নির্দেশকের সুযোগটি মূলত অভিভাবকের সুযোগ থেকে উত্তরাধিকার সূত্রে পরিণত করে। কোনও ধারণা কেন এটি এখনও এটি ছাড়া কাজ করে?
জিম কুপার

4
কোনও শিশু স্কোপ (মোছা scope:true) কাজ করে না কারণ নির্দেশিকাটি কোনও নতুন সুযোগ তৈরি করে না এবং সুতরাং ফাংশনে scopeআপনি যে সম্পত্তিটি উল্লেখ করেছেন সেটি linkহ'ল আগের 'পিতামাতার' স্কোপের মতো ঠিক একই সুযোগ।
ক্লার্ক প্যান

এই ক্ষেত্রে আবেদন করা যথেষ্ট (আমার উত্তর দেখুন)।
রাজকোক

4
$ ইভেন্টটি কী?
সিএমসিডিগ্রাগনকাই

12

স্পষ্টত hideButtonপিতামাতার সুযোগ কল করুন।

এই হিটটি এখানে: http://jsfiddle.net/pXej2/5/

এবং এখানে আপডেট করা এইচটিএমএল:

<div ng-app="myModule" ng-controller="myController">
    <input ng-model="showIt"></input>
    <button ng-hide="$parent.hideButton()" confirm="Are you sure?" confirm-action="doIt()">Do It</button>
</div>

কাজের সমাধানের জন্য +1 আমি আসলে $ পিতামাতার সাথে ব্যবহার করার চেষ্টা করেছি এবং যখন এটি কাজ করে না তখন হাল ছেড়ে দেয়। আপনার সমাধানটি দেখার পরে, আমি আরও ঘনিষ্ঠভাবে দেখেছি এবং প্রমাণিত হয়েছে যে আমি যে প্যারামিটারগুলি দিয়ে যাচ্ছি সেগুলিতে আমি $ পিতামাতার সাথে যুক্ত করতে ব্যর্থ হয়েছি (আমার মূল ফিজলে প্রদর্শিত হয়নি)। উদাহরণস্বরূপ, যদি আমি লুকিয়ে বাটন () ফাংশনটিতে শোটি পাস করতে চাই তবে আমাকে $ প্যারেন্টহাইডবটন ($ প্যারেন্ট.শোআইটি) ব্যবহার করতে হবে এবং আমি দ্বিতীয় $ পিতামাতাকে অনুপস্থিত। আমি ক্লার্কের উত্তরটি গ্রহণ করতে যাচ্ছি, তবে, যেহেতু সমাধানটি আমার নির্দেশকের ব্যবহারকারীর পক্ষে তাদের they পিতামাতার যুক্ত হওয়া দরকার তা জানতে প্রয়োজন হয় না। অন্তর্দৃষ্টি জন্য ধন্যবাদ!
জিম कूপার

1

আমার একটাই সমস্যা হ'ল আমি যদি কোনও ব্যবস্থাকে বিচ্ছিন্ন সুযোগে না পাস করি তবে কীভাবে আমি প্যারেন্ট স্কোপটিতে কল করব?

এখানে একটি জিসফিল রয়েছে যেখানে আমি বিচ্ছিন্ন সুযোগ ব্যবহার করছি না এবং এনজি-হাইডটি ভাল কাজ করছে, তবে অবশ্যই, নিশ্চিতকরণের কলটি () কাজ করে না এবং আমি কীভাবে এটি কাজ করব তা জানি না।

প্রথমে একটি ছোট বিষয়: এই ক্ষেত্রে বাহ্যিক নিয়ন্ত্রকের সুযোগটি নির্দেশকের স্কোপের অভিভাবকীয় সুযোগ নয়; বাইরের নিয়ামকের সুযোগ হ'ল নির্দেশকের সুযোগ scope অন্য কথায়, নির্দেশে ব্যবহৃত ভেরিয়েবলের নামগুলি নিয়ামকের স্কোপে সরাসরি দেখা হবে।

এর পরে, লেখাটি attrs.confirmAction()কাজ করে না কারণ attrs.confirmActionএই বোতামটির জন্য,

<button ... confirm-action="doIt()">Do It</button>

স্ট্রিং "doIt()", এবং আপনি কোনও স্ট্রিং কল করতে পারবেন না, যেমন "doIt()"()

আপনার প্রশ্নটি আসলে:

স্ট্রিং হিসাবে যখন আমার কোনও নামটির নাম হয় আমি কীভাবে কল করব?

জাভাস্ক্রিপ্টে আপনি বেশিরভাগ ক্ষেত্রে ডট স্বরলিপি ব্যবহার করে ফাংশনগুলি কল করেন:

some_obj.greet()

তবে আপনি অ্যারে স্বরলিপিটিও ব্যবহার করতে পারেন:

some_obj['greet']

সূচকের মানটি কীভাবে স্ট্রিং হয় তা দ্রষ্টব্য । সুতরাং, আপনার নির্দেশিকায় আপনি কেবল এটি করতে পারেন:

  link: function (scope, element, attrs) {

    element.bind('click', function (e) {

      if (confirm(attrs.confirm)) {
        var func_str = attrs.confirmAction;
        var func_name = func_str.substring(0, func_str.indexOf('(')); // Or func_str.match(/[^(]+/)[0];
        func_name = func_name.trim();

        console.log(func_name); // => doIt
        scope[func_name]();
      }
    });
  }

+1 যেহেতু ফাংশনটি বিশ্লেষণের ধারণাটি জটিল ছিল এবং অনুরূপ তবে অন্য একটি সমস্যা নিয়ে আমাকে সহায়তা করেছিল। ধন্যবাদ!
আনমল সারাফ
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.