Angularjs, rotalar arasında kapsam geçme


87

Birkaç sayfaya yayılan bir formla ilgili bir durumum var (ideal olmayabilir, ama bu böyle). Siz ilerledikçe doldurulan formun tamamı için tek bir kapsam olmasını istiyorum, böylece kullanıcı adımlar arasında gidip gelirse durumu hatırlaması kolay olur.

Bu yüzden çok sözde kodla yapmam gerekiyor:

  1. Ayarlamak $scope.val = <Some dynamic data>
  2. Bir bağlantıya tıklayın ve yeni bir şablona yönlendirilin (muhtemelen aynı denetleyiciyle).
  3. $scope.val yine de son sayfadakiyle aynı değerde olmalıdır.

Kapsam için bir şekilde ısrarcı veriler bunun için doğru yol mu yoksa başka bir yol var mı? Elbette bir veritabanına kaydetme dışında, yollar arasında kalıcı bir kapsamı olan bir denetleyici bile yaratabilir misiniz?


Ganaraj'a bir ek olarak: Burada, farklı denetleyicilerin iletişim kurmasını nasıl sağlayacağınıza dair bir ekran kaydı içeren gerçekten güzel bir blog girişi bulacaksınız. Ayrıca oynayabileceğiniz birkaç yararlı jsfiddle var. onehungrymind.com/angularjs-communicating-between-controllers Umarım yardımcı olur.
F Lekschas

Yanıtlar:


138

Bir hizmet uygulamanızın ömrü boyunca devam edeceği için bir hizmet kullanmanız gerekir.

Bir kullanıcıya ait verileri kaydetmek istediğinizi varsayalım

Hizmeti şu şekilde tanımlarsınız:

app.factory("user",function(){
        return {};
});

İlk kontrol cihazınızda:

app.controller( "RegistrationPage1Controller",function($scope,user){
    $scope.user = user;
    // and then set values on the object
    $scope.user.firstname = "John";
    $scope.user.secondname = "Smith";
});

app.controller( "RegistrationSecondPageController",function($scope,user){
        $scope.user = user;
        // and then set values on the object
        $scope.user.address = "1, Mars";

    });

6
Ahhh! Bunu daha önce denedim, ancak çalışmasını sağlayamadım çünkü her iki rota için de aynı denetleyiciyi kullandım, bu nedenle her yeni rotada varsayılan değerler önceki sayfada girdiklerimin üzerine yazacaktı. İki denetleyiciyle veya varsayılan değerler olmadan bu artık gerçekleşmez. Teşekkürler!
Erik Honn

1
Ne hakkında Value Recipe docs.angularjs.org/guide/providers gibi, myApp.value('clientId', 'a12345654321x');aynı zamanda bu yolları arasındaki kalıcıdır?
The Bndr

@TheBndr: Olmalı. Değerler, anladığım kadarıyla yalnızca özel bir hizmet biçimidir.
Robert Koritnik

3
Sayfayı yeniden yüklerseniz hizmetler verileri kalıcı hale getirmez ... Dolayısıyla, formunuzun 4. sayfasındaysanız ve bu sayfayı yeniden yüklerseniz, doldurulan tüm verileri kaybedersiniz.
danielrvt

1
Güzel cevap! Bir yan nokta olarak, bu yanıtı alan kişiler için bir stil kılavuzu - kendileri kurucu olmayan hizmetler (yani yeni XX olarak kullanılan) küçük harf deve olarak adlandırılmalıdır: github.com/mgechev/angularjs-style-guide .
Matt Byrne

9

Hizmet çalışacaktır, ancak bunu yalnızca sıradan kapsamları ve denetleyicileri kullanarak yapmanın mantıklı bir yolu, denetleyicilerinizi ve öğelerinizi modelinizin yapısını yansıtacak şekilde ayarlamaktır. Özellikle, bir üst kapsam oluşturan bir ana öğeye ve denetleyiciye ihtiyacınız vardır. Formun ayrı ayrı sayfaları, ebeveynin alt öğesi olan bir görünümde yer almalıdır. Üst kapsam, alt öğe görünümü güncellendiğinde bile devam eder.

Ui-yönlendirici kullandığınızı varsayıyorum, böylece yuvalanmış adlandırılmış görünümlere sahip olabilirsiniz. Sonra sözde kodda:

<div ng-controller="WizardController">
  <div name="stepView" ui-view/>
</div>

Daha sonra WizardController, çok sayfalı formun ("sihirbaz" olarak bahsettiğim) adımlarında korumak istediğiniz kapsam değişkenlerini tanımlar. Ardından rotalarınız stepViewyalnızca güncellenecektir . Her adımın kendi şablonları, denetleyicileri ve kapsamları olabilir, ancak bunların kapsamları sayfadan sayfaya kaybolur. Ancak WizardController'daki kapsamlar tüm sayfalarda korunur.

WizardController kapsamlarını alt denetleyicilerden güncellemek için, her kapsam değişkeni için WizardController'da $scope.$parent.myProp = 'value'bir işlev gibi sözdizimi kullanmanız veya tanımlamanız gerekir setMyProp. Aksi takdirde, ana kapsam değişkenlerini doğrudan alt denetleyicilerden ayarlamaya çalışırsanız, yalnızca alt öğe üzerinde yeni bir kapsam değişkeni oluşturarak ana değişkeni gölgelendirirsiniz.

Açıklaması zor ve tam bir örnek olmadığı için özür dilerim. Temel olarak, formunuzun tüm sayfalarında korunacak bir üst kapsam oluşturan bir üst denetleyici istiyorsunuz.


1
Bu, ui-router ile işe yarar evet (ve böyle bir sayfa tasarlamanın oldukça güzel bir yolu), ancak kutudan çıktığı gibi değil. Kutudan çıkar çıkmaz hizmet yöntemi, gitmenin yoludur.
Erik Honn

1
Açıklığa kavuşturmak için, üst kapsam özellikleri her zaman alt kapsam tarafından miras alınacaktır. Ancak, alt kapsamdan bir üst kapsam özelliği ayarlamak isterseniz, buna üst öğe üzerinde erişmeniz gerekir, aksi takdirde alt kapsamda aynı adda yeni bir özellik oluşturursunuz. Bir üst kapsam özelliği ayarlamak şu şekilde yapılabilir:$scope.$parent.myProp = 'hello world';
mbursill

1
Bu, bir hizmeti kullanmaktan çok daha hoş bir yaklaşımdır. Hizmetler tekildir, dolayısıyla orada tanımlanan herhangi bir durum uygulama için küreseldir. Kullanıcı sihirbazdan kısmen çıkarsa ve ardından yeniden başlatırsa, her çıkış noktasında hizmeti düzgün bir şekilde temizlemediğinizden emin olmadığınız sürece, hizmette önceki çalıştırmadan kalan durum olacaktır, ancak bu oldukça kolayca önemli bir bakım baş ağrısına dönüşür!
Dan King

Bu cevaba çok daha hevesli
Kurai Bankusu

Angular UI Router kullanmıyorsanız aklınıza gelen ilk şey hizmetlerdir. UI Router kullanıyorsanız, yine de, iç içe görünümler arasında bilgileri kalıcı hale getirebilen iç içe çözümlere sahiptir. Bunun ana kapsama erişmeye çalışmaktan daha temiz bir yaklaşım olacağını düşünüyorum. medium.com/opinionated-angularjs/…
losmescaleros

6

Veriler, denetleyiciler arasında iki yolla aktarılabilir

  1. $rootScope
  2. Modeli

Aşağıdaki örnek, model kullanılarak değerlerin geçişini göstermektedir

app.js

angular.module('testApp')
  .controller('Controller', Controller)
  .controller('ControllerTwo', ControllerTwo)
  .factory('SharedService', SharedService);

SharedService.js

function SharedService($rootScope){

 return{
    objA: "value1",
    objB: "value2"
  }
}

// A denetleyicisindeki değeri değiştirin

Controller.js

function Controller($scope, SharedService){

 $scope.SharedService = SharedService;

 $scope.SharedService.objA = "value1 modified";
}

// controllertwo'daki değere erişin

ControllerTwo.js

function ControllerTwo($scope, SharedService){

 $scope.SharedService = SharedService;

 console.log("$scope.SharedService.objA"+$scope.SharedService.objA); // Prints "value1 modified"
}

Bu yardımcı olur umarım.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.