क्या आप निर्माण पर एक AngularJS नियंत्रक के मापदंडों को पारित कर सकते हैं?


278

मेरे पास उपयोगकर्ता, नाम, ईमेल, आदि के गुणों को अपडेट करने के लिए एपीआई के साथ संचार करने के लिए एक नियंत्रक जिम्मेदार है, प्रत्येक उपयोगकर्ता के पास 'id'सर्वर है जो प्रोफ़ाइल पृष्ठ देखे जाने पर सर्वर से पारित हो जाता है।

मैं इस मान को AngularJS कंट्रोलर को देना चाहूंगा ताकि यह पता चले कि वर्तमान उपयोगकर्ता के लिए API एंट्री पॉइंट क्या है। मैंने मान को पास करने की कोशिश की है ng-controller। उदाहरण के लिए:

function UserCtrl(id, $scope, $filter) {

$scope.connection = $resource('api.com/user/' + id)

और HTML में

<body ng-controller="UserCtrl({% id %})">

जहां {% id %}सर्वर से भेजे गए आईडी को प्रिंट करें। लेकिन मुझे त्रुटियाँ मिलती हैं।

इसके निर्माण पर एक नियंत्रक में एक मूल्य पारित करने का सही तरीका क्या है?


6
यदि आपके पास url के भाग के रूप में id है तो आप केवल url को पढ़ सकते हैं
akonsu

मुझे बहुत ही समस्या थी और मैंने इसे हल कर दिया जैसे मैंने अपने उत्तर में पोस्ट किया है। कभी-कभी पुस्तकालयों का उपयोग करके हम जावास्क्रिप्ट फ़ंक्शन कॉल की सरल मौलिक अवधारणा को अनदेखा कर देते हैं।
जिगर पटेल

@nickponline 21+ के बाद भी आपको लगता है कि यह संभव नहीं है?
om471987

जवाबों:


362

टिप्पणियाँ:

यह उत्तर पुराना है। यह केवल अवधारणा का प्रमाण है कि वांछित परिणाम कैसे प्राप्त किया जा सकता है। हालाँकि, यह नीचे दिए गए कुछ टिप्पणियों के अनुसार सबसे अच्छा समाधान नहीं हो सकता है। मेरे पास निम्नलिखित दृष्टिकोण का समर्थन करने या अस्वीकार करने के लिए कोई दस्तावेज नहीं है। कृपया इस विषय पर आगे की चर्चा के लिए नीचे कुछ टिप्पणियों का संदर्भ लें।

मूल उत्तर:

मैंने इसका उत्तर हां में दिया है कि आप इसका उपयोग कर सकते हैं ng-initऔर एक सरल इनिट फ़ंक्शन कर सकते हैं ।

प्लंकर पर इसका उदाहरण यहां दिया गया है

एचटीएमएल

<!DOCTYPE html>
<html ng-app="angularjs-starter">
  <head lang="en">
    <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.0.3/angular.min.js"></script>
    <script src="app.js"></script>
  </head>  
  <body ng-controller="MainCtrl" ng-init="init('James Bond','007')">
    <h1>I am  {{name}} {{id}}</h1>
  </body>
</html>

जावास्क्रिप्ट

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

app.controller('MainCtrl', function($scope) {

  $scope.init = function(name, id)
  {
    //This function is sort of private constructor for controller
    $scope.id = id;
    $scope.name = name; 
    //Based on passed argument you can make a call to resource
    //and initialize more objects
    //$resource.getMeBond(007)
  };


});

5
इसके लिए धन्यवाद - मुझे बहुत सिर खुजाने से बचाया, और यह मेरी स्थिति के लिए पूरी तरह से काम किया। मुझे अपने नियंत्रक को ऑब्जेक्ट आईडी के साथ आरंभीकृत करना था, और यह सिर्फ सही था।
मेसनोइस

26
डॉक्स से :The only appropriate use of ngInit for aliasing special properties of ngRepeat, as seen in the demo below. Besides this case, you should use controllers rather than ngInit to initialize values on a scope.
सेर्गेई ग्रोली

8
उत्तर यह स्पष्ट करता है कि इस दृष्टिकोण के खिलाफ डॉक्टर की सिफारिश, लेकिन क्या कोई मुझे बता सकता है कि डॉक्स आधिकारिक समाधान कहां प्रदान करता है?
माइकल पेल

53
वैसे मुझे लगता है कि डॉक्स बिना कारण बताए इस दृष्टिकोण के खिलाफ सिफारिश करने में गरीब हैं। मुझे लगता है कि यह एक शानदार तरीका है। यदि फ्रेमवर्क लेखक यह नहीं चाहते हैं कि फ्रेमवर्क का उपयोग उनके "गलत" तरीके से किया जाए, तो उन्हें उस "गलत" तरीके से उपयोग करना संभव नहीं बनाना चाहिए ... और "के रूप में मार्गदर्शन प्रदान करें" सही रास्ता!
शॉन डे वेट

2
चेतावनी का एक शब्द - यदि आप एक स्कोप मान को बाँधने का प्रयास कर रहे हैं, या वास्तव में ऐसा कुछ भी करते हैं जो नियंत्रक फ़ंक्शन में मौजूद मान की अपेक्षा करता है, तो यह होने से पहले ही नियंत्रक फ़ंक्शन को चलाताng-init है - देखें plnkr.co/edit / donCm6FRBSX9oENXh9WJ? p = पूर्वावलोकन
drzaus

143

मुझे इसके लिए बहुत देर हो चुकी है और मुझे पता नहीं है कि क्या यह एक अच्छा विचार है, लेकिन आप $attrsनियंत्रक फ़ंक्शन में इंजेक्टेबल को शामिल कर सकते हैं, जिससे एक तत्व पर प्रदान किए गए "तर्कों" का उपयोग करके नियंत्रक को प्रारंभिक किया जा सकता है, जैसे।

app.controller('modelController', function($scope, $attrs) {
    if (!$attrs.model) throw new Error("No model for modelController");

    // Initialize $scope using the value of the model attribute, e.g.,
    $scope.url = "http://example.com/fetch?model="+$attrs.model;
})

<div ng-controller="modelController" model="foobar">
  <a href="{{url}}">Click here</a>
</div>

फिर, कोई विचार नहीं है अगर यह एक अच्छा विचार है, लेकिन यह काम करने लगता है और एक और विकल्प है।


3
मैं इस दृष्टिकोण का उपयोग करके किसी वस्तु को कैसे पास करूंगा? var obj = {a: 1, b: 2};
नील

3
हाइब्रिड ऐप बनाने की समस्या का यह एक बहुत ही उचित समाधान है।
सुपरलाइनरी

2
@ नील: आपको अपनी जसन ऑब्जेक्ट को सख्त करना होगा और फिर इसे कंट्रोलर के अंदर पार्स करना होगा। अच्छा समाधान नहीं है, लेकिन यह काम कर सकता है। माइकल का समाधान स्ट्रिंग-जैसे मापदंडों के लिए ठीक है ...
एम का आउर टॉप '

1
इस का उपयोग करने से वास्तव में और अधिक विश्वसनीय है ng-init- आप एक गुंजाइश मूल्य के लिए बाँध की कोशिश कर रहे हैं, यह पहले से ही नियंत्रक समारोह चलाए जाने के दौरान से पहले ng-initहोता है - देखना plnkr.co/edit/donCm6FRBSX9oENXh9WJ?p=preview
drzaus

2
मुझे निर्देश आदि के साथ पहिया को फिर से मजबूत करने की आवश्यकता नहीं है। यदि आपके पास एक नियंत्रक है जिसे आप कुछ अलग-अलग आरंभीकरण मापदंडों के साथ कई दृश्यों में उपयोग करना चाहते हैं, तो यह सबसे आसान और सबसे विश्वसनीय समाधान है।
एरिक एच।

39

यह भी काम करता है।

जावास्क्रिप्ट:

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

app.controller('MainCtrl', function($scope, name, id) {
    $scope.id = id;
    $scope.name = name;
    // and more init
});

एचटीएमएल:

<!DOCTYPE html>
<html ng-app="angularApp">
  <head lang="en">
    <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.0.3/angular.min.js"></script>
    <script src="app.js"></script>
    <script>
       app.value("name", "James").value("id", "007");
    </script>
  </head>
  <body ng-controller="MainCtrl">
    <h1>I am  {{name}} {{id}}</h1>
  </body>
</html>

3
यह एक अच्छा समाधान है जो मौजूदा कंस्ट्रक्टर इंजेक्शन तंत्र के साथ काम करता है। आप संक्षेप में, 'नाम' और 'आईडी' नामक दो सरल सेवाएं बना रहे हैं। इंजेक्टर निर्माण के दौरान उन्हें नाम से मिलान करने का ख्याल रखता है। देखें: docs.angularjs.org/guide/providers
टोड

1
अच्छा लगा। ध्यान दें कि यह वस्तुओं के साथ भी काम करता है, न कि केवल आदिम प्रकार के तार।
jbustamovej

मुझे यह समाधान बेहतर लगा। मैं पैरामीटर के माध्यम से अपने डुप्लिकेट किए गए कोड को संशोधित करने में सक्षम था। चीयर्स!
एजेंटबॉक्स सेप

यह सबसे मुहावरेदार तरीका लगता है, लेकिन मुझे यकीन नहीं है कि यह कोणीय टीम द्वारा सिफारिश की गई है
VinGarcia

क्या यह अनिवार्य रूप से वैश्विक कुंजी / मूल्य जोड़े स्थापित करता है? क्या इन्हें किसी दिए गए कंट्रोलर इंस्टेंसेस से अलग किया जा सकता है, ताकि इसे मुख्य नियंत्रक के तहत चाइल्ड कंट्रोलर्स पर ही उठाया जाए? यदि ऐसा नहीं लगता है कि यह वास्तव में खिड़की के स्तर पर एक नियमित वैश्विक जावास्क्रिप्ट चर सेट करने की तुलना में बहुत अलग नहीं है।
जिपरसन

16

दृश्य को कॉन्फ़िगर नहीं करना चाहिए

कोणीय में, टेम्प्लेट को कभी भी कॉन्फ़िगरेशन को निर्देशित नहीं करना चाहिए, जो स्वाभाविक रूप से लोगों की इच्छा है जब वे एक टेम्प्लेट फ़ाइल से नियंत्रकों के लिए तर्क पारित करना चाहते हैं। यह एक फिसलन ढलान बन जाता है। यदि कॉन्फ़िगरेशन सेटिंग्स को टेम्प्लेट में हार्ड-कोडित किया जाता है (जैसे कि एक निर्देश या नियंत्रक तर्क विशेषता), तो आप अब उस टेम्प्लेट को किसी भी चीज़ के लिए फिर से उपयोग नहीं कर सकते हैं। जल्द ही आप उस टेम्पलेट का फिर से उपयोग करना चाहते हैं, लेकिन अलग-अलग कॉन्फ़िगरेशन के साथ और अब ऐसा करने के लिए आप या तो पूर्व-प्रसंस्करण करने के लिए टेम्पलेटों को इंजेक्ट करेंगे, इससे पहले कि यह कोणीय में पास हो जाए या विशालकाय थूक को बाहर निकालने के लिए बड़े पैमाने पर निर्देशों का उपयोग करें। HTML के ब्लॉक ताकि आप रैपर div को छोड़कर नियंत्रक HTML के सभी का पुनः उपयोग कर सकें और यह तर्क है। छोटी परियोजनाओं के लिए यह कोई बड़ी बात नहीं है। कुछ बड़े (कोणीय एक्सेल में) के लिए, यह बदसूरत जल्दी हो जाता है।

वैकल्पिक: मॉड्यूल

इस प्रकार का कॉन्फ़िगरेशन वह है जो मॉड्यूल को संभालने के लिए डिज़ाइन किया गया था। कई कोणीय ट्यूटोरियल में लोगों के पास अपने संपूर्ण अनुप्रयोग के लिए एक ही मॉड्यूल होता है, लेकिन वास्तव में सिस्टम को डिज़ाइन किया गया है और यह पूरी तरह से कई छोटे मॉड्यूलों का समर्थन करता है जो कुल आवेदन के छोटे टुकड़ों को लपेटते हैं। आदर्श रूप से, नियंत्रकों, मॉड्यूल आदि को अलग-अलग फाइलों में घोषित किया जाएगा और विशिष्ट पुन: प्रयोज्य विखंडू में एक साथ सिलाई की जाएगी। जब आपका आवेदन इस तरह से डिज़ाइन किया जाता है, तो आपको आसान नियंत्रक तर्कों के अलावा बहुत सारे उपयोग मिलते हैं।

नीचे दिए गए उदाहरण में 2 मॉड्यूल हैं, एक ही नियंत्रक का फिर से उपयोग करना, लेकिन प्रत्येक अपनी स्वयं की कॉन्फ़िगरेशन सेटिंग्स के साथ। उस कॉन्फ़िगरेशन सेटिंग्स का उपयोग करके निर्भरता इंजेक्शन के माध्यम से पारित किया जाता है module.value। यह कोणीय तरीके से पालन करता है क्योंकि हमारे पास निम्नलिखित हैं: कंस्ट्रक्टर निर्भरता इंजेक्शन, पुन: प्रयोज्य नियंत्रक कोड, पुन: प्रयोज्य नियंत्रक टेम्प्लेट (नियंत्रक डिव आसानी से एनजी-शामिल किए जा सकते हैं), एचटीएमएल के बिना आसानी से इकाई-परीक्षण योग्य प्रणाली और अंतिम रूप से पुन: प्रयोज्य। एक साथ टुकड़ों को सिलाई के लिए वाहन के रूप में मॉड्यूल।

यहाँ एक उदाहरण है:

<!-- index.html -->
<div id="module1">
    <div ng-controller="MyCtrl">
        <div>{{foo}}</div>
    </div>
</div>
<div id="module2">
    <div ng-controller="MyCtrl">
        <div>{{foo}}</div>
    </div>
</div>
<script>
    // part of this template, or a JS file designed to be used with this template
    angular.element(document).ready(function() {
        angular.bootstrap(document.getElementById("module1"), ["module1"]);
        angular.bootstrap(document.getElementById("module2"), ["module2"]);
    });
</script>

<!-- scripts which will likely in be in their seperate files -->
<script>
    // MyCtrl.js
    var MyCtrl = function($scope, foo) {
    $scope.foo = foo;
    }

    MyCtrl.$inject = ["$scope", "foo"];

    // Module1.js
    var module1 = angular.module('module1', []);
    module1.value("foo", "fooValue1");
    module1.controller("MyCtrl", MyCtrl);

    // Module2.js file
    var module2 = angular.module('module2', []);
    module2.value("foo", "fooValue2");
    module2.controller("MyCtrl", MyCtrl);
</script>

कार्य करते हुए देखें: jsFiddle


मैंने पहले ही उत्थान कर लिया है, लेकिन मैं आपके योगदान के लिए धन्यवाद देना चाहता हूं। इस जवाब ने मुझे एक बेहतर रास्ते पर ला खड़ा किया। स्टैकओवरफ़्लो सबसे अच्छा है जब लोग सर्वोत्तम प्रथाओं को साझा करते हैं और न कि केवल हैक किए गए स्निपेट। यह शानदार है: "टेम्पलेट को कॉन्फ़िगरेशन को कभी भी निर्धारित नहीं करना चाहिए, जो कि लोगों की इच्छा है कि जब वे टेम्पलेट फ़ाइल से नियंत्रकों के लिए तर्क पारित करना चाहते हैं"। मामले के दिल में लेजर दृष्टि होने के लिए धन्यवाद।
पेस्टोफैगस

15

जैसे @akonsu और Nigel Findlater सुझाव देते हैं, आप url को पढ़ सकते हैं जहाँ url index.html#/user/:idसाथ है $routeParams.idऔर नियंत्रक के अंदर इसका उपयोग करते हैं।

आपका ऐप:

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

app.config(['$routeProvider', function($routeProvider) {
    $routeProvider.when('/:type/:id', {templateUrl: 'myView.html', controller: 'myCtrl'});
}]);

संसाधन सेवा

app.factory('MyElements', ['$resource', function($resource) {
     return $resource('url/to/json/:type/:id', { type:'@type', id:'@id' });
}]);

नियंत्रक

app.controller('MyCtrl', ['$scope', '$routeParams', 'MyElements', function($scope, $routeParams, MyElements) {
    MyElements.get({'type': $routeParams.type, "id": $routeParams.id }, function(elm) {
        $scope.elm = elm;
    })
}]);

उसके बाद, elmदृश्य में सुलभ है id


8

यदि ng-initवस्तुओं को पास करने के लिए नहीं है $scope, तो आप हमेशा अपना निर्देश लिख सकते हैं। तो यहाँ मुझे क्या मिला है:

http://jsfiddle.net/goliney/89bLj/

जावास्क्रिप्ट:

var app = angular.module('myApp', []);
app.directive('initData', function($parse) {
    return function(scope, element, attrs) {
        //modify scope
        var model = $parse(attrs.initData);
        model(scope);
    };
});

function Ctrl1($scope) {
    //should be defined
    $scope.inputdata = {foo:"east", bar:"west"};
}

एचटीएमएल:

<div ng-controller="Ctrl1">
    <div init-data="inputdata.foo=123; inputdata.bar=321"></div>
</div>

लेकिन मेरा दृष्टिकोण केवल वस्तुओं को संशोधित कर सकता है, जो पहले से ही नियंत्रक पर परिभाषित हैं।


संदर्भ के लिए यह महान काम करता है लेकिन कोणीय के वर्तमान संस्करण पर यह $ attrs (बनाम अटार्स) है
डिनिस क्रूज़

8

ऐसा लगता है कि आपके लिए सबसे अच्छा समाधान वास्तव में एक निर्देश है। यह आपको अभी भी अपने नियंत्रक की अनुमति देता है, लेकिन इसके लिए कस्टम गुणों को परिभाषित करता है।

यदि आपको लपेटने के दायरे में चर तक पहुंच की आवश्यकता हो तो इसका उपयोग करें:

angular.module('myModule').directive('user', function ($filter) {
  return {
    link: function (scope, element, attrs) {
      $scope.connection = $resource('api.com/user/' + attrs.userId);
    }
  };
});

<user user-id="{% id %}"></user>

यदि आपको लपेटने के दायरे में चर तक पहुंच की आवश्यकता नहीं है, तो इसका उपयोग करें:

angular.module('myModule').directive('user', function ($filter) {
  return {
    scope: {
      userId: '@'
    },
    link: function (scope, element, attrs) {
      $scope.connection = $resource('api.com/user/' + scope.userId);
    }
  };
});

<user user-id="{% id %}"></user>

7

मुझे $ मार्गप्रोपाइडर उपयोगी से चर मिलते हुए मिले।

उदाहरण के लिए, आप कई स्क्रीन के लिए एक नियंत्रक MyController का उपयोग करते हैं, कुछ बहुत ही महत्वपूर्ण चर "mySuperConstant" के अंदर से गुजरते हैं।

उस सरल संरचना का उपयोग करें:

Router:

$routeProvider
            .when('/this-page', {
                templateUrl: 'common.html',
                controller: MyController,
                mySuperConstant: "123"
            })
            .when('/that-page', {
                templateUrl: 'common.html',
                controller: MyController,
                mySuperConstant: "456"
            })
            .when('/another-page', {
                templateUrl: 'common.html',
                controller: MyController,
                mySuperConstant: "789"
            })

MyController:

    MyController: function ($scope, $route) {
        var mySuperConstant: $route.current.mySuperConstant;
        alert(mySuperConstant);

    }

6

आप यह कर सकते हैं जब उदाहरण के लिए मार्गों की स्थापना

 .when('/newitem/:itemType', {
            templateUrl: 'scripts/components/items/newEditItem.html',
            controller: 'NewEditItemController as vm',
            resolve: {
              isEditMode: function () {
                return true;
              }
            },
        })

और बाद में इसका उपयोग करें

(function () {
  'use strict';

  angular
    .module('myApp')
    .controller('NewEditItemController', NewEditItemController);

  NewEditItemController.$inject = ['$http','isEditMode',$routeParams,];

  function NewEditItemController($http, isEditMode, $routeParams) {
    /* jshint validthis:true */

    var vm = this;
    vm.isEditMode = isEditMode;
    vm.itemType = $routeParams.itemType;
  }
})();

इसलिए जब हम हमारे द्वारा भेजे गए मार्ग को सेट करते हैं: आइटम टाइप करें और इसे बाद में $ मार्गप्रेम से हटा दें।


4

नियंत्रक में $ मार्गप्रेमों को इंजेक्ट करके किसी नियंत्रक के मापदंडों को पारित करने का एक और तरीका है और फिर यहां वर्णित url मापदंडों का उपयोग करके AngularJS में क्वेरी मापदंडों को पढ़ने का सबसे संक्षिप्त तरीका क्या है?


3

यह सवाल पुराना है, लेकिन मैं लंबे समय से इस समस्या का जवाब पाने के लिए संघर्ष कर रहा था जो मेरी जरूरतों के लिए काम करेगा और इसे आसानी से पूरा नहीं करेगा। मेरा मानना ​​है कि मेरा निम्नलिखित समाधान वर्तमान में स्वीकृत एक की तुलना में बहुत बेहतर है, शायद क्योंकि कोणीय ने कार्यक्षमता को जोड़ा है क्योंकि यह प्रश्न मूल रूप से सामने आया था।

लघु उत्तर, Module.value विधि का उपयोग करने से आप एक नियंत्रक कंस्ट्रक्टर में डेटा पास कर सकते हैं।

मेरे प्लंकर को यहाँ देखें

मैं एक मॉडल ऑब्जेक्ट बनाता हूं, फिर इसे मॉड्यूल के नियंत्रक के साथ संबद्ध करता हूं, इसे 'मॉडल' नाम से संदर्भित करता हूं

HTML / JS

  <html>
  <head>
    <script>
      var model = {"id": 1, "name":"foo"};

      $(document).ready(function(){
        var module = angular.module('myApp', []);
        module.value('model', model);
        module.controller('MyController', ['model', MyController]);
        angular.bootstrap(document, ['myApp']);
      });

      function confirmModelEdited() {
        alert("model name: " + model.name + "\nmodel id: " + model.id);
      }
    </script>

  </head>
  <body >
      <div ng-controller="MyController as controller">
        id: {{controller.model.id}} <br>
        name: <input ng-model="controller.model.name"/>{{controller.model.name}}
        <br><button ng-click="controller.incrementId()">increment ID</button>
        <br><button onclick="confirmModelEdited()">confirm model was edited</button>
    </div>
  </body>

</html>

मेरे नियंत्रक में कंस्ट्रक्टर तब उसी पहचानकर्ता 'मॉडल' के साथ एक पैरामीटर को स्वीकार करता है जिसे वह तब एक्सेस कर सकता है।

नियंत्रक

function MyController (model) {
  this.model = model;
}

MyController.prototype.incrementId = function() {
  this.model.id = this.model.id + 1;
}

टिप्पणियाँ:

मैं बूटस्ट्रैपिंग के मैनुअल इनिशियलाइज़ेशन का उपयोग कर रहा हूं , जो मुझे कोणीय पर भेजने से पहले अपने मॉडल को इनिशियलाइज़ करने की अनुमति देता है। यह मौजूदा कोड के साथ बहुत अधिक अच्छी तरह से खेलता है, जैसा कि आप अपने प्रासंगिक डेटा को सेट करने के लिए इंतजार कर सकते हैं और जब चाहें तब केवल अपने ऐप के कोणीय सबसेट को संकलित कर सकते हैं।

प्लंकर में मैंने उस मॉडल ऑब्जेक्ट के मूल्यों को सचेत करने के लिए एक बटन जोड़ा है जिसे शुरू में जावास्क्रिप्ट में परिभाषित किया गया था और कोणीय में पारित किया गया था, बस यह पुष्टि करने के लिए कि कोणीय वास्तव में मॉडल ऑब्जेक्ट का संदर्भ दे रहा है, बजाय इसे कॉपी करने और कॉपी के साथ काम करने के।

इस लाइन पर:

module.controller('MyController', ['model', MyController]);

मैं एक समारोह इनलाइन के रूप में घोषित करने के बजाय मॉड्यूल.कंट्रोलर फ़ंक्शन में MyController ऑब्जेक्ट पास कर रहा हूं। मुझे लगता है कि यह हमें हमारे नियंत्रक ऑब्जेक्ट को और अधिक स्पष्ट रूप से परिभाषित करने की अनुमति देता है, लेकिन कोणीय प्रलेखन इसे इनलाइन करने की कोशिश करता है इसलिए मुझे लगा कि यह स्पष्टीकरण को सहन करेगा।

मैं "$ गुंजाइश" चर का उपयोग करने के बजाय MyController की "यह" संपत्ति के लिए "सिंटैक्स" के रूप में "नियंत्रक" और मानों को असाइन कर रहा हूं। मेरा मानना ​​है कि यह $ गुंजाइश का उपयोग करके ठीक काम करेगा, नियंत्रक असाइनमेंट फिर कुछ इस तरह दिखेगा:

module.controller('MyController', ['$scope', 'model', MyController]);

और नियंत्रक निर्माता के पास इस तरह एक हस्ताक्षर होगा:

function MyController ($scope, model) {

यदि आप जो भी कारण चाहते हैं, तो आप इस मॉडल को दूसरे मॉड्यूल के मूल्य के रूप में भी संलग्न कर सकते हैं, जिसे आप तब अपने प्राथमिक मॉड्यूल पर निर्भरता के रूप में संलग्न करते हैं।

मेरा मानना ​​है कि उसका समाधान वर्तमान में स्वीकृत एक से बेहतर है क्योंकि

  1. नियंत्रक को दिया गया मॉडल वास्तव में एक जावास्क्रिप्ट ऑब्जेक्ट है, न कि एक स्ट्रिंग जिसका मूल्यांकन किया जाता है। यह ऑब्जेक्ट का एक सही संदर्भ है और इसमें परिवर्तन इस मॉडल ऑब्जेक्ट के अन्य संदर्भों को प्रभावित करता है।
  2. कोणीय का कहना है कि एनजी-इनिट के स्वीकृत उत्तर का दुरुपयोग एक दुरुपयोग है, जो यह समाधान नहीं करता है।

जिस तरह से कोणीय ने अन्य सभी उदाहरणों में काम किया है, मैंने देखा है कि नियंत्रक ने मॉडल के डेटा को परिभाषित किया है, जिसने मुझे कभी भी समझ में नहीं आया है, मॉडल और नियंत्रक के बीच कोई अलगाव नहीं है, जो वास्तव में ऐसा नहीं लगता है मेरे लिए एम.वी.सी. यह समाधान आपको वास्तव में एक पूरी तरह से अलग मॉडल ऑब्जेक्ट की अनुमति देता है जिसे आप नियंत्रक में पास करते हैं। ध्यान दें, यदि आप एनजी-इन-डायरेक्टिव का उपयोग करते हैं, तो आप अपने सभी कोणीय HTML को एक अलग फ़ाइल में रख सकते हैं, अपने मॉडल दृश्य और नियंत्रक को पूरी तरह से अलग मॉड्यूलर टुकड़ों में अलग कर सकते हैं।


2

यदि कोणीय-यूआई-राउटर का उपयोग किया जाता है, तो यह सही समाधान है: https://github.com/angular-ui/ui-router/wiki#resolve

मूल रूप से, आप नियंत्रक के तुरंत बाद "समाधान" करने के लिए निर्भरता का एक सेट घोषित करते हैं। आप अपने "राज्यों" में से प्रत्येक के लिए निर्भरता की घोषणा कर सकते हैं। ये निर्भरताएं तब कंट्रोलर के "कंस्ट्रक्टर" में पारित हो जाती हैं।


1

ऐसा करने का एक तरीका एक अलग सेवा होगी, जिसका उपयोग उन तर्कों के लिए एक 'पोत' के रूप में किया जा सकता है, जहां वे सार्वजनिक डेटा सदस्य हैं।


सबसे अच्छा जवाब, IMO। मैं वर्तमान में उन उपयोगकर्ताओं के लिए कुछ मामलों में ब्राउज़र स्टोरेज का उपयोग करता हूं जो F5 को हिट करने का साहस करते हैं, इसलिए यह स्थिति बनी हुई है।
छात्रावास

1

मुझे वास्तव में मेरे विशेष उपयोग के मामले में कोई भी समाधान पसंद नहीं आया, इसलिए मुझे लगा कि मैंने जो किया है, वह पोस्ट करूँगा क्योंकि मैंने इसे यहाँ नहीं देखा।

मैं बस एनजी-रिपीट लूप के भीतर एक निर्देशक की तरह एक नियंत्रक का उपयोग करना चाहता था:

<div ng-repeat="objParameter in [{id:'a'},{id:'b'},{id:'c'}]">
  <div ng-controller="DirectiveLikeController as ctrl"></div>
</div>

अब, objParameterप्रत्येक DirectiveLikeController के भीतर निर्माण पर पहुंचने के लिए (या किसी भी समय अप-टू-डेट objParameter प्राप्त करने के लिए), मुझे केवल $ स्कोप और कॉल इंजेक्ट करने की आवश्यकता है $scope.$eval('objParameter'):

var app = angular.module('myapp', []);
app.controller('DirectiveLikeController',['$scope'], function($scope) {
   //print 'a' for the 1st instance, 'b' for the 2nd instance, and 'c' for the 3rd.
   console.log($scope.$eval('objParameter').id); 
});

केवल वास्तविक नकारात्मक पहलू जो मुझे दिखाई देता है वह यह है कि पैरामीटर नियंत्रक को यह जानने की आवश्यकता है कि पैरामीटर नाम है objParameter


0

नहीं, यह संभव नहीं है। मुझे लगता है कि आप http://docs.angularjs.org/api/ng.directive:ngInit हैक के रूप में एनजी-इनिट का उपयोग कर सकते हैं ।


4
मैं अलग होने की भीख माँगता हूँ, लेकिन आप एनजी-इनिट का उपयोग करके और इनिट फ़क्शन का उपयोग करके इसे पूरा कर सकते हैं।
जिगर पटेल

चेतावनी का एक शब्द - यदि आप एक स्कोप मान को बाँधने का प्रयास कर रहे हैं, या वास्तव में ऐसा कुछ भी करते हैं जो नियंत्रक फ़ंक्शन में मौजूद मान की अपेक्षा करता है, तो यह होने से पहले ही नियंत्रक फ़ंक्शन को चलाताng-init है - देखें plnkr.co/edit / donCm6FRBSX9oENXh9WJ? p = पूर्वावलोकन
drzaus

हाँ यह संभव है। बहुत कम से कम, आप डेटा का उपयोग करेंगे- परम या जो भी हो। लेकिन यह निश्चित रूप से संभव है।
जुआन

0

यहां एक समाधान है (Marcin Wyszynski के सुझाव पर आधारित) जो काम करता है जहां आप अपने नियंत्रक में एक मान पारित करना चाहते हैं, लेकिन आप स्पष्ट रूप से अपने html में नियंत्रक की घोषणा नहीं कर रहे हैं (जो एनजी-इनिट की आवश्यकता लगती है) - यदि, उदाहरण के लिए, विकल्प आप एनजी-व्यू के साथ अपने टेम्प्लेट का प्रतिपादन कर रहे हैं और मार्गप्रोवाइडर के माध्यम से संबंधित मार्ग के लिए प्रत्येक नियंत्रक की घोषणा कर रहे हैं।

जे एस

messageboard.directive('currentuser', ['CurrentUser', function(CurrentUser) {
  return function(scope, element, attrs) {
    CurrentUser.name = attrs.name;
  };
}]);

एचटीएमएल

<div ng-app="app">
  <div class="view-container">
    <div ng-view currentuser name="testusername" class="view-frame animate-view"></div>
  </div>
</div>

इस समाधान में, CurrentUser एक ऐसी सेवा है जिसे किसी भी नियंत्रक में .name संपत्ति के साथ इंजेक्ट किया जा सकता है।

दो नोट:

  • एक समस्या जो मैंने देखी है, वह यह है कि। नियंत्रक लोड होने के बाद। क्या सेवा तक प्रतीक्षा करने का एक साफ तरीका है।

  • यह अपने कोणीय ऐप में वर्तमान उपयोगकर्ता को प्राप्त करने के लिए एक बहुत ही आसान तरीका की तरह महसूस करता है, जो सभी कोणीय के बाहर रखे प्रमाणीकरण के साथ है। आपके पास एक गैर-लॉग इन उपयोगकर्ताओं को HTML में मिल रहे गैर-लॉग इन को रोकने के लिए पहले से ही हो सकता है जहां आपका कोणीय ऐप बूटस्ट्रैप्ड हो, और उस HTML के भीतर आप उपयोगकर्ता के नाम और यहां तक ​​कि अगर आप उपयोगकर्ता के विवरण के साथ बातचीत करना चाहते हैं तो भी उनकी आईडी को इंटरपोल कर सकते हैं। अपने कोणीय एप्लिकेशन से http अनुरोधों के माध्यम से। आप एक 'डिफ़ॉल्ट अतिथि उपयोगकर्ता' के साथ कोणीय ऐप का उपयोग करने के लिए उपयोगकर्ताओं को गैर-लॉग की अनुमति दे सकते हैं। इस दृष्टिकोण के खराब होने पर कोई सलाह स्वागत योग्य होगी - समझदार होना बहुत आसान है!)


0

यह @Michael टिलर के उत्कृष्ट उत्तर का विस्तार है । उसका उत्तर $attrsनियंत्रक में ऑब्जेक्ट को इंजेक्ट करके दृश्य से वैरिएबल को आरम्भ करने के लिए काम करता है । समस्या तब होती है यदि $routeProviderराउटर द्वारा नेविगेट करने पर उसी नियंत्रक से कॉल किया जाता है । तब आपको इंजेक्टर त्रुटि मिलती है Unknown provider : $attrsProviderक्योंकि $attrsजब दृश्य संकलित किया जाता है तो केवल इंजेक्शन के लिए उपलब्ध होता है। $routeParamsमार्ग से नियंत्रक को $attrsप्रारंभ करने और देखने से नियंत्रक को प्रारंभ करते समय समाधान को चर (foo) से गुजरना होता है । यहाँ मेरा समाधान है।

मार्ग से

$routeProvider.
        when('/mypage/:foo', {
            templateUrl: 'templates/mypage.html',
            controller: 'MyPageController',
            caseInsensitiveMatch: true,
            resolve: {
                $attrs: function () {
                    return {};
                }
            }
        });

यह एक url जैसे संभालता है '/mypage/bar'। जैसा कि आप देख सकते हैं कि foo को url param द्वारा पारित किया गया है और हम बिना किसी इंजेक्टर त्रुटियों के $injectorलिए एक रिक्त वस्तु प्रदान करते $attrsहैं।

दृश्य से

<div ng-controller="MyPageController" data-foo="bar">

</div>

अब नियंत्रक

var app = angular.module('myapp', []);
app.controller('MyPageController',['$scope', '$attrs', '$routeParams'], function($scope, $attrs, $routeParams) {
   //now you can initialize foo. If $attrs contains foo, it's been initialized from view
   //else find it from $routeParams
   var foo = $attrs.foo? $attrs.foo : $routeParams.foo;
   console.log(foo); //prints 'bar'

});
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.