Angularjs, phạm vi di chuyển giữa các tuyến đường


87

Tôi có một tình huống với một biểu mẫu trải dài trên nhiều trang (có thể không phải là lý tưởng, nhưng đó là cách nó được thực hiện). Tôi muốn có một phạm vi cho toàn bộ biểu mẫu được điền khi bạn thực hiện, để nếu người dùng qua lại giữa các bước sẽ dễ dàng ghi nhớ trạng thái.

Vì vậy, tôi cần phải làm, trong mã rất giả:

  1. Bộ $scope.val = <Some dynamic data>
  2. Nhấp vào một liên kết và được chuyển đến một mẫu mới (có thể với cùng một bộ điều khiển).
  3. $scope.val vẫn nên giữ nguyên giá trị như ở trang cuối cùng.

Bằng cách nào đó, dữ liệu liên tục cho phạm vi có phải là cách thích hợp để giải quyết vấn đề này hay là có một số cách khác? Bạn thậm chí có thể tạo bộ điều khiển có phạm vi liên tục giữa các tuyến, tất nhiên là ngoại trừ việc lưu nó trong cơ sở dữ liệu.


Cũng giống như một phần bổ sung cho ganaraj: Tại đây, bạn sẽ tìm thấy một mục blog thực sự hay với một video truyền hình về cách để các bộ điều khiển khác nhau giao tiếp. Ngoài ra còn có một số jsfiddles hữu ích để chơi với. onehungrymind.com/angularjs-communicating-between-controllers Tôi hy vọng nó sẽ hữu ích.
F Lekschas 14/12/12

Câu trả lời:


138

Bạn cần sử dụng một dịch vụ vì một dịch vụ sẽ tồn tại trong suốt vòng đời ứng dụng của bạn.

Giả sử bạn muốn lưu dữ liệu liên quan đến người dùng

Đây là cách bạn xác định dịch vụ:

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

Trong bộ điều khiển đầu tiên của bạn:

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! Tôi đã thử điều đó trước đây nhưng không thể làm cho nó hoạt động vì tôi đã sử dụng cùng một bộ điều khiển cho cả hai tuyến, vì vậy tại mỗi tuyến mới, các giá trị mặc định sẽ ghi đè những giá trị tôi đã nhập trên trang trước. Với hai bộ điều khiển hoặc không có giá trị mặc định, điều này không còn xảy ra nữa. Cảm ơn!
Erik Honn 14/12/12

1
Còn về Value Recipe docs.angularjs.org/guide/providers , giống như myApp.value('clientId', 'a12345654321x');nó có liên tục giữa các tuyến không?
The Bndr

@TheBndr: Đúng là như vậy. Giá trị chỉ là một dạng dịch vụ đặc biệt như tôi hiểu.
Robert Koritnik

3
Các dịch vụ sẽ không duy trì dữ liệu nếu bạn tải lại trang ... Vì vậy, nếu bạn đang ở trang 4 của biểu mẫu và tải lại trang đó, bạn sẽ mất tất cả dữ liệu đã điền.
danielrvt

1
Câu trả lời rất hay! Bên cạnh đó, hướng dẫn về kiểu cho những người sử dụng câu trả lời này - các dịch vụ không phải là công cụ tạo (tức là được sử dụng như XX mới) phải được đặt tên là lạc đà viết thường: github.com/mgechev/angularjs-style-guide .
Matt Byrne

9

Dịch vụ sẽ hoạt động, nhưng một cách hợp lý để thực hiện nó chỉ bằng cách sử dụng các phạm vi và bộ điều khiển thông thường là thiết lập bộ điều khiển và phần tử của bạn để nó phản ánh cấu trúc mô hình của bạn. Đặc biệt, bạn cần một phần tử cha và bộ điều khiển thiết lập phạm vi cha. Các trang riêng lẻ của biểu mẫu phải nằm trong chế độ xem là trang con đối với trang chính. Phạm vi chính vẫn tồn tại ngay cả khi chế độ xem con được cập nhật.

Tôi giả sử bạn đang sử dụng ui-router để bạn có thể có các khung nhìn được đặt tên lồng nhau. Sau đó, trong mã giả:

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

Sau đó, WizardController xác định các biến phạm vi mà bạn muốn duy trì qua các bước của biểu mẫu nhiều trang (mà tôi đang đề cập đến như một "trình hướng dẫn"). Sau đó, các tuyến đường của bạn sẽ stepViewchỉ cập nhật . Mỗi bước có thể có các mẫu, bộ điều khiển và phạm vi riêng, nhưng phạm vi của chúng bị mất từ ​​trang này sang trang khác. Nhưng phạm vi trong WizardController được giữ nguyên trên tất cả các trang.

Để cập nhật phạm vi WizardController từ bộ điều khiển con, bạn sẽ cần sử dụng cú pháp như $scope.$parent.myProp = 'value'hoặc xác định một hàm setMyProptrên WizardController cho mỗi biến phạm vi. Ngược lại, nếu bạn cố gắng đặt các biến phạm vi cha trực tiếp từ bộ điều khiển con, thì cuối cùng bạn sẽ chỉ tạo một biến phạm vi mới trên chính con, che khuất biến cha.

Hơi khó giải thích và tôi xin lỗi vì thiếu một ví dụ đầy đủ. Về cơ bản, bạn muốn một bộ điều khiển cha thiết lập phạm vi cha, phạm vi này sẽ được giữ nguyên trên tất cả các trang trong biểu mẫu của bạn.


1
Điều này sẽ hoạt động với ui-router vâng (và đó là một cách khá hay để thiết kế một trang như vậy), nhưng không phải là ngoại lệ. Ngoài ra, phương pháp dịch vụ là con đường để đi.
Erik Honn

1
Chỉ cần làm rõ, các thuộc tính phạm vi cha sẽ luôn được kế thừa bởi phạm vi con. Tuy nhiên, nếu bạn muốn đặt thuộc tính phạm vi cha từ phạm vi con, bạn cần phải truy cập thuộc tính đó trên phạm vi cha, nếu không, bạn đang tạo một thuộc tính mới cùng tên trên phạm vi con. Đặt thuộc tính phạm vi chính có thể được thực hiện bằng cách truy cập:$scope.$parent.myProp = 'hello world';
mdowill

1
Đây là một cách tiếp cận đẹp hơn nhiều so với sử dụng dịch vụ. Các dịch vụ là các đơn lẻ, vì vậy bất kỳ trạng thái nào được xác định ở đó là toàn cầu đối với ứng dụng. Nếu người dùng thoát khỏi trình hướng dẫn một cách thông qua, sau đó khởi động lại nó, sẽ có trạng thái còn sót lại trong dịch vụ từ lần chạy trước - trừ khi bạn đảm bảo rằng bạn dọn dẹp dịch vụ đúng cách tại mọi điểm thoát, nhưng điều này có thể khá dễ dàng trở thành một vấn đề bảo trì đau đầu đáng kể!
Dan King

Nhiều hơn nữa quan tâm đến câu trả lời này
Kurai Bankusu

Dịch vụ là điều đầu tiên bạn cần nghĩ đến nếu bạn không sử dụng Angular UI Router. Tuy nhiên, nếu bạn đang sử dụng Bộ định tuyến giao diện người dùng, nó có các phân giải lồng nhau có thể duy trì thông tin giữa các khung nhìn lồng nhau. Tôi nghĩ rằng đó sẽ là một cách tiếp cận rõ ràng hơn là cố gắng truy cập phạm vi chính. medium.com/opinionated-angularjs/…
losmescaleros

5

Dữ liệu có thể được truyền giữa các bộ điều khiển thông qua hai cách

  1. $rootScope
  2. Mô hình

Mẫu bên dưới minh họa việc truyền các giá trị bằng cách sử dụng mô hình

app.js

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

SharedService.js

function SharedService($rootScope){

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

// Sửa đổi giá trị trong bộ điều khiển A

Controller.js

function Controller($scope, SharedService){

 $scope.SharedService = SharedService;

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

// Truy cập giá trị trong điều khiển hai

ControllerTwo.js

function ControllerTwo($scope, SharedService){

 $scope.SharedService = SharedService;

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

Hi vọng điêu nay co ich.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.