Bisakah Anda meneruskan parameter ke pengontrol AngularJS saat pembuatan?


278

Saya memiliki pengontrol yang bertanggung jawab untuk berkomunikasi dengan API untuk memperbarui properti pengguna, nama, email, dll. Setiap pengguna memiliki 'id'yang dilewatkan dari server ketika halaman profil dilihat.

Saya ingin meneruskan nilai ini ke pengontrol AngularJS sehingga ia tahu apa titik masuk API untuk pengguna saat ini. Saya sudah mencoba meneruskan nilai ng-controller. Sebagai contoh:

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

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

dan dalam HTML

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

di mana {% id %}mencetak id yang dikirim dari server. tapi saya mendapatkan kesalahan.

Apa cara yang benar untuk meneruskan nilai ke controller pada pembuatannya?


6
jika Anda memiliki id sebagai bagian dari url maka Anda bisa membaca url
akonsu

Saya memiliki masalah yang sangat mirip dan saya menyelesaikannya karena saya telah memposting dalam jawaban saya. Terkadang menggunakan perpustakaan kita mengabaikan konsep dasar sederhana dari pemanggilan fungsi JavaScript.
Jigar Patel

@nickponline Setelah 21+ Anda masih berpikir itu tidak mungkin?
om471987

Jawaban:


362

Catatan:

Jawaban ini sudah tua. Ini hanyalah bukti konsep tentang bagaimana hasil yang diinginkan dapat dicapai. Namun, itu mungkin bukan solusi terbaik sesuai beberapa komentar di bawah ini. Saya tidak memiliki dokumentasi untuk mendukung atau menolak pendekatan berikut. Silakan merujuk ke beberapa komentar di bawah ini untuk diskusi lebih lanjut tentang topik ini.

Jawaban asli:

Saya menjawab ini untuk Ya Anda benar-benar dapat melakukannya menggunakan ng-initdan fungsi init sederhana.

Berikut ini contohnya pada plunker

HTML

<!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>

JavaScript

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
Terima kasih untuk ini - menyelamatkan saya dari banyak goresan kepala, dan itu bekerja dengan baik untuk situasi saya. Saya harus menginisialisasi controller saya dengan ID objek, dan ini tepat.
Masonoise

26
Dari dokumen :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.
Sergey Goliney

8
Jawabannya memperjelas bahwa rekomendasi dokter menentang pendekatan ini, tetapi dapatkah seseorang menunjuk saya ke tempat dokter memberikan solusi resmi?
Michael Pell

53
Yah saya pikir dokumen miskin hanya merekomendasikan terhadap pendekatan ini tanpa memberikan alasan mengapa. Saya pikir ini adalah pendekatan yang brilian. Jika kerangka penulis tidak ingin kerangka yang digunakan dalam apa yang bagi mereka cara "salah", maka mereka seharusnya tidak memungkinkan untuk digunakan dengan cara "salah" itu ... dan memberikan panduan untuk " cara yang benar!
Shawn de Wet

2
kata peringatan - jika Anda mencoba untuk mengikat ke nilai lingkup, atau benar-benar melakukan apa pun yang mengharapkan nilai hadir dalam fungsi controller, itu sudah menjalankan fungsi controller sebelum ng-initterjadi - lihat plnkr.co/edit / donCm6FRBSX9oENXh9WJ? p = preview
drzaus

143

Saya sangat terlambat untuk hal ini dan saya tidak tahu apakah ini ide yang bagus, tetapi Anda dapat memasukkan $attrsinjeksi ke dalam fungsi pengontrol yang memungkinkan pengontrol diinisialisasi menggunakan "argumen" yang disediakan pada suatu elemen, misalnya

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>

Sekali lagi, tidak tahu apakah ini ide yang bagus, tetapi tampaknya berhasil dan merupakan alternatif lain.


3
Bagaimana saya melewati objek menggunakan pendekatan ini? var obj = {a: 1, b: 2};
Neil

3
Ini adalah solusi yang sangat masuk akal untuk masalah menghasilkan aplikasi hybrid.
superluminary

2
@ Neil: Anda harus merangkai objek json Anda dan kemudian menguraikannya di dalam controller. Bukan solusi yang lebih baik, tetapi mungkin berhasil. Solusi Michael baik untuk parameter seperti string ...
M'sieur Toph '

1
ini sebenarnya lebih dapat diandalkan daripada menggunakan ng-init- jika Anda mencoba untuk mengikat ke nilai lingkup, itu sudah menjalankan fungsi controller sebelum ng-initterjadi - lihat plnkr.co/edit/donCm6FRBSX9oENXh9WJ?p=preview
drzaus

2
Saya tidak mendapatkan semua reinventing the wheel dengan arahan dll. Jika Anda memiliki controller yang ingin Anda gunakan dalam beberapa tampilan dengan beberapa parameter inisialisasi yang berbeda, ini adalah solusi termudah dan paling dapat diandalkan.
Eric H.

39

Ini juga berfungsi.

Javascript:

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

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

Html:

<!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
Ini adalah solusi yang baik yang bekerja dengan mekanisme injeksi konstruktor yang ada. Anda, pada dasarnya, menciptakan dua layanan sederhana yang disebut 'nama' dan 'id'. Injektor menangani pencocokan nama mereka selama konstruksi. Lihat: bagian Resep Nilai docs.angularjs.org/guide/providers
Todd

1
Bagus. Perhatikan ini juga berfungsi dengan objek, bukan hanya tipe primitif seperti string.
jbustamovej

Saya suka solusi ini lebih baik. Saya dapat memodulasi kode yang digandakan melalui parameter yang lewat. Bersulang!
agentpx

Ini sepertinya cara yang paling idiomatis, tapi saya tidak yakin itu direkomendasikan oleh tim sudut
VinGarcia

Apakah ini pada dasarnya mengatur pasangan kunci / nilai global? Apakah ini dapat dicakup ke instance pengontrol yang diberikan sehingga hanya diambil pada pengontrol anak di bawah pengontrol utama? Jika tidak, sepertinya ini tidak jauh berbeda dari hanya mengatur variabel Javascript global reguler di tingkat jendela.
jpierson

16

Tampilan tidak boleh menentukan konfigurasi

Di Angular, templat tidak boleh mendikte konfigurasi, yang secara inheren diinginkan orang ketika mereka ingin memberikan argumen kepada pengontrol dari file templat. Ini menjadi lereng yang licin. Jika pengaturan konfigurasi dikodekan dalam templat (seperti oleh atribut argumen direktif atau pengontrol), Anda tidak bisa lagi menggunakan kembali templat itu untuk apa pun kecuali penggunaan tunggal itu. Sebentar lagi Anda akan ingin menggunakan kembali templat itu, tetapi dengan konfigurasi yang berbeda dan sekarang untuk melakukannya Anda akan melakukan pra-pemrosesan templat untuk menyuntikkan variabel sebelum diteruskan ke sudut atau menggunakan arahan masif untuk mengeluarkan raksasa blok HTML sehingga Anda menggunakan kembali semua HTML controller kecuali untuk div pembungkus dan argumennya. Untuk proyek kecil itu bukan masalah besar. Untuk sesuatu yang besar (keunggulan sudut), ia menjadi cepat jelek.

Alternatif: Modul

Jenis konfigurasi inilah yang dirancang untuk ditangani oleh modul. Dalam banyak tutorial sudut orang memiliki modul tunggal untuk seluruh aplikasi mereka, tetapi sistem ini dirancang dan sepenuhnya mendukung banyak modul kecil yang masing-masing membungkus potongan-potongan kecil dari total aplikasi. Idealnya, pengontrol, modul, dll akan dideklarasikan dalam file terpisah dan dijahit bersama dalam potongan yang dapat digunakan kembali secara spesifik. Ketika aplikasi Anda dirancang dengan cara ini, Anda mendapatkan banyak penggunaan kembali selain argumen pengontrol yang mudah.

Contoh di bawah ini memiliki 2 modul, menggunakan kembali kontroler yang sama, tetapi masing-masing dengan pengaturan konfigurasi sendiri. Pengaturan konfigurasi dilewatkan melalui ketergantungan menggunakan injeksi module.value. Ini mengikuti cara sudut karena kami memiliki yang berikut: injeksi dependensi konstruktor, kode pengontrol yang dapat digunakan kembali, templat pengontrol yang dapat digunakan kembali (div pengontrol dapat dengan mudah dimasukkan dengan ng-include), sistem unit-testable yang mudah tanpa HTML, dan terakhir dapat digunakan kembali modul sebagai kendaraan untuk menjahit potongan.

Ini sebuah contoh:

<!-- 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>

Lihat dalam aksi: jsFiddle .


saya sudah ter-upgrade, tetapi saya ingin menyuarakan terima kasih atas kontribusi Anda. jawaban ini membuat saya berada di jalur yang lebih baik. stackoverflow adalah yang terbaik ketika orang-orang berbagi praktik terbaik dan bukan hanya potongan hacky. ini brilian: "templat tidak boleh mendikte konfigurasi, yang secara inheren keinginan orang ketika mereka ingin meneruskan argumen ke pengendali dari file templat". terima kasih karena memiliki penglihatan laser ke inti masalah.
pestophagous

15

Seperti @akonsu dan Nigel Findlater menyarankan, Anda dapat membaca url mana url adalah index.html#/user/:iddengan $routeParams.iddan menggunakannya dalam controller.

aplikasi Anda:

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

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

layanan sumber daya

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

controller

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

kemudian, elmdapat diakses dalam tampilan tergantung pada id.


8

Jika ng-initbukan karena meneruskan objek $scope, Anda selalu dapat menulis arahan Anda sendiri. Jadi inilah yang saya dapat:

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

Javasript:

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"};
}

Html:

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

Tetapi pendekatan saya hanya bisa memodifikasi objek, yang sudah didefinisikan pada controller.


Untuk referensi ini berfungsi dengan baik tetapi pada versi angular saat ini adalah $ attrs (vs attrs)
Dinis Cruz

8

Sepertinya solusi terbaik untuk Anda sebenarnya adalah arahan. Ini memungkinkan Anda untuk tetap memiliki pengontrol Anda, tetapi menentukan properti khusus untuk itu.

Gunakan ini jika Anda memerlukan akses ke variabel dalam lingkup pembungkus:

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>

Gunakan ini jika Anda tidak memerlukan akses ke variabel dalam lingkup pembungkus:

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

Saya menemukan variabel lewat dari $ routeProvider berguna.

Misalnya, Anda menggunakan satu kontroler MyController untuk beberapa layar, melewati beberapa variabel penting "mySuperConstant" di dalamnya.

Gunakan struktur sederhana itu:

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

Anda dapat melakukannya saat mengatur rute misalnya

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

Dan kemudian menggunakannya sebagai

(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;
  }
})();

Jadi di sini ketika kita mengatur rute yang kami kirim: itemType dan retrive nanti dari $ routeParams.



3

Pertanyaan ini sudah lama tetapi saya berjuang untuk waktu yang lama mencoba mendapatkan jawaban untuk masalah ini yang akan bekerja untuk kebutuhan saya dan tidak mudah menemukannya. Saya percaya solusi saya berikut ini jauh lebih baik daripada yang diterima saat ini, mungkin karena sudut telah menambahkan fungsionalitas sejak pertanyaan ini awalnya diajukan.

Jawaban singkat, menggunakan metode Module.value memungkinkan Anda untuk meneruskan data ke konstruktor pengontrol.

Lihat penyedot saya di sini

Saya membuat objek model, lalu mengaitkannya dengan pengontrol modul, merujuknya dengan nama 'model'

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>

Konstruktor di controller saya kemudian menerima parameter dengan 'model' pengidentifikasi yang sama yang kemudian dapat diakses.

Pengendali

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

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

Catatan:

Saya menggunakan inisialisasi manual bootstrap , yang memungkinkan saya untuk menginisialisasi model saya sebelum mengirimnya ke sudut. Ini memainkan jauh lebih baik dengan kode yang ada, karena Anda dapat menunggu untuk menyiapkan data yang relevan dan hanya mengkompilasi bagian sudut dari aplikasi Anda sesuai permintaan saat Anda mau.

Dalam plunker saya telah menambahkan tombol untuk mengingatkan nilai-nilai objek model yang awalnya didefinisikan dalam javascript dan diteruskan ke sudut, hanya untuk mengonfirmasi bahwa sudut benar-benar merujuk objek model, daripada menyalinnya dan bekerja dengan salinan.

Di baris ini:

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

Saya meneruskan objek MyController ke fungsi Module.controller, daripada mendeklarasikan sebagai fungsi inline. Saya pikir ini memungkinkan kita untuk mendefinisikan objek controller kita dengan lebih jelas, tetapi dokumentasi Angular cenderung melakukannya secara inline, jadi saya pikir ini memerlukan klarifikasi.

Saya menggunakan sintaks "controller as" dan memberikan nilai ke properti "this" dari MyController, daripada menggunakan variabel "$ scope". Saya percaya ini akan bekerja dengan baik menggunakan $ scope juga, tugas controller akan terlihat seperti ini:

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

dan konstruktor controller akan memiliki tanda tangan seperti ini:

function MyController ($scope, model) {

Jika karena alasan apa pun yang Anda inginkan, Anda juga bisa melampirkan model ini sebagai nilai dari modul kedua, yang kemudian Anda lampirkan sebagai ketergantungan pada modul utama Anda.

Saya percaya solusinya jauh lebih baik daripada yang diterima saat ini karena

  1. Model yang diteruskan ke controller sebenarnya adalah objek javascript, bukan string yang dievaluasi. Ini adalah referensi yang benar ke objek dan perubahan itu mempengaruhi referensi lain ke objek model ini.
  2. Angular mengatakan bahwa penggunaan jawaban ng-init yang diterima adalah penyalahgunaan, yang tidak dilakukan solusi ini.

Cara Angular tampaknya bekerja di sebagian besar semua contoh lain yang pernah saya lihat memiliki controller mendefinisikan data model, yang tidak pernah masuk akal bagi saya, tidak ada pemisahan antara model dan controller, yang tidak benar-benar tampak seperti MVC bagiku. Solusi ini memungkinkan Anda untuk benar-benar memiliki objek model yang benar-benar terpisah yang Anda lewati ke controller. Yang juga perlu diperhatikan, jika Anda menggunakan perintah ng-include Anda dapat meletakkan semua html sudut Anda dalam file terpisah, sepenuhnya memisahkan tampilan model Anda dan pengontrol menjadi potongan modular terpisah.


2

Jika menggunakan angular-ui-router, maka ini adalah solusi yang tepat: https://github.com/angular-ui/ui-router/wiki#resolve

Pada dasarnya, Anda mendeklarasikan seperangkat dependecies untuk "menyelesaikan" sebelum controller dipakai. Anda dapat mendeklarasikan dependensi untuk masing-masing "negara" Anda. Ketergantungan ini kemudian diteruskan dalam "konstruktor" pengontrol.


1

Salah satu cara untuk melakukan itu adalah memiliki layanan terpisah yang dapat digunakan sebagai 'kapal' untuk argumen di mana mereka adalah anggota data publik.


Jawaban terbaik, IMO. Saat ini saya juga menggunakan penyimpanan browser dalam beberapa kasus untuk para pengguna yang berani menekan F5, jadi keadaan ini dipertahankan.
Asrama

1

Saya tidak terlalu menyukai solusi apa pun di sini untuk kasus penggunaan khusus saya, jadi saya pikir saya akan memposting apa yang saya lakukan karena saya tidak melihatnya di sini.

Saya hanya ingin menggunakan pengontrol lebih seperti arahan, dalam loop ng-repeat:

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

Sekarang, untuk mengakses objParameterkreasi on dalam setiap DirectiveLikeController (atau untuk mendapatkan objParameter terkini kapan saja), yang perlu saya lakukan adalah menyuntikkan $ scope dan menelepon $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); 
});

Satu-satunya downside nyata yang saya lihat adalah bahwa ia membutuhkan pengendali induk untuk mengetahui bahwa parameter tersebut dinamai objParameter.


0

Tidak, itu tidak mungkin. Saya pikir Anda dapat menggunakan ng-init sebagai hack http://docs.angularjs.org/api/ng.directive:ngInit .


4
Saya mohon berbeda tetapi Anda dapat melakukannya menggunakan ng-init dan menggunakan init fuction.
Jigar Patel

kata peringatan - jika Anda mencoba untuk mengikat ke nilai lingkup, atau benar-benar melakukan apa pun yang mengharapkan nilai hadir dalam fungsi controller, itu sudah menjalankan fungsi controller sebelum ng-initterjadi - lihat plnkr.co/edit / donCm6FRBSX9oENXh9WJ? p = preview
drzaus

Ya itu mungkin. Paling tidak, Anda akan menggunakan params data atau apa pun. Tapi itu pasti mungkin.
Juan

0

Berikut ini adalah solusi (berdasarkan saran Marcin Wyszynski) yang berfungsi di mana Anda ingin memberikan nilai ke controller Anda tetapi Anda tidak secara eksplisit mendeklarasikan controller di html Anda (yang tampaknya diperlukan oleh ng-init) - jika, misalnya, Anda merender template Anda dengan ng-view dan mendeklarasikan masing-masing controller untuk rute yang sesuai melalui routeProvider.

JS

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

html

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

Dalam solusi ini, CurrentUser adalah layanan yang dapat disuntikkan ke pengontrol apa pun, dengan properti .name yang tersedia.

Dua catatan:

  • masalah yang saya temui adalah .name akan diatur setelah controller dimuat, jadi sebagai solusinya saya memiliki batas waktu singkat sebelum memberikan nama pengguna pada ruang lingkup controller. Apakah ada cara menunggu yang rapi sampai nama telah ditentukan pada layanan?

  • ini terasa seperti cara yang sangat mudah untuk mendapatkan pengguna saat ini ke Aplikasi Angular Anda dengan semua otentikasi disimpan di luar Angular. Anda bisa memiliki before_filter untuk mencegah pengguna yang tidak masuk log masuk ke html tempat aplikasi Angular Anda di-boot, dan di dalam html itu Anda bisa menginterpolasi nama pengguna yang masuk dan bahkan ID mereka jika Anda ingin berinteraksi dengan detail pengguna melalui permintaan http dari aplikasi Angular Anda. Anda dapat mengizinkan pengguna yang tidak masuk untuk menggunakan Aplikasi Angular dengan 'pengguna tamu' default. Setiap saran tentang mengapa pendekatan ini buruk akan diterima - rasanya terlalu mudah untuk masuk akal!)


0

Ini adalah perluasan dari jawaban luar biasa @Michael Tiller . Jawabannya berfungsi untuk menginisialisasi variabel dari tampilan dengan menyuntikkan $attrsobjek ke controller. Masalah terjadi jika pengontrol yang sama dipanggil dari $routeProvidersaat Anda menavigasi dengan perutean. Kemudian Anda mendapatkan kesalahan injector Unknown provider : $attrsProviderkarena $attrshanya tersedia untuk injeksi ketika tampilan dikompilasi. Solusinya adalah untuk melewati variabel (foo) melalui $routeParamsketika menginisialisasi pengontrol dari rute dan $attrsketika menginisialisasi pengontrol dari tampilan. Inilah solusi saya.

Dari Route

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

Ini menangani url seperti '/mypage/bar'. Seperti yang Anda lihat, foo dilewatkan oleh param url dan kami menyediakan $injectorobjek kosong $attrsagar tidak ada kesalahan injektor.

Dari View

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

</div>

Sekarang controller

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'

});
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.