আমি কৌনিক 2 এর উপাদানগুলির মধ্যে ডেটা কীভাবে ভাগ করব?


84

কৌণিক 1.XX এ আপনি কেবল একই পরিষেবাটির জন্য জিজ্ঞাসা করেন এবং পরিষেবাতে ডেটা ভাগ করা সম্ভব করে, আপনি একই উদাহরণটি শেষ করেন।

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

আমি কি ভুল করছি? এটি কি নিজেই সেই প্যাটার্নটি ভুল (ডেটা ভাগ করার জন্য কোনও পরিষেবা ব্যবহার করে) বা আমার কি পরিষেবাটিকে একক হিসাবে চিহ্নিত করতে হবে (অ্যাপ্লিকেশনটির একটি উদাহরণের মধ্যে) বা কিছু?

আমি 2.0.0-alpha.27/ বিটিডব্লিউতে আছি

আমি টীকাতে appInjector(এখন সম্পাদনা করুন providers) মাধ্যমে একটি পরিষেবা ইনজেক্ট করি @Componentএবং তারপরে কনস্ট্রাক্টরে একটি রেফারেন্স সংরক্ষণ করি। এটি উপাদানটিতে স্থানীয়ভাবে কাজ করে - কেবল উপাদানগুলির জুড়ে নয় (তারা একই পরিষেবা উদাহরণটি ভাগ করে না) যেমন আমি ভেবেছিলাম তারা করবে।

আপডেট : অ্যাঙ্গুলার ২.০.০ অনুসারে আমাদের এখন @ngModule রয়েছে যেখানে আপনি providersসম্পত্তিটির অধীনে পরিষেবাটি সংজ্ঞায়িত করবেন @ngModule। এটি সেই মডিউলের প্রতিটি উপাদান, পরিষেবা, ইত্যাদিতে সেই পরিষেবাটির একই উদাহরণটি নিশ্চিত করবে। https://angular.io/docs/ts/latest/guide/ngmodule.html# প্রোভাইডার

আপডেট : সাধারণভাবে কৌণিক এবং এফই বিকাশের ক্ষেত্রে অনেক কিছুই ঘটেছে। @ নোরিরিকো যেমন উল্লেখ করেছেন, আপনি এনজিআরএক্সের মতো একটি রাজ্য পরিচালনা ব্যবস্থাও ব্যবহার করতে পারেন: https://ngrx.io/


কৌণিক উপাদান মধ্যে ডেটা ভাগ করে নেওয়ার জন্য ছয় পদ্ধতি: - angulartutorial.net/2017/12/...
Prashobh

আপনি যদি এখানে
পৌঁছে যান

উত্তর:


63

একটি সার্ভিস সিঙ্গলটন একটি দুর্দান্ত সমাধান। অন্য উপায় - data/events bindings

এখানে উভয়ের উদাহরণ:

class BazService{
  n: number = 0;
  inc(){
    this.n++;
  }
}

@Component({
  selector: 'foo'
})
@View({
  template: `<button (click)="foobaz.inc()">Foo {{ foobaz.n }}</button>`
})
class FooComponent{
  constructor(foobaz: BazService){
    this.foobaz = foobaz;
  }
}

@Component({
  selector: 'bar',
  properties: ['prop']
})
@View({
  template: `<button (click)="barbaz.inc()">Bar {{ barbaz.n }}, Foo {{ prop.foobaz.n }}</button>`
})
class BarComponent{
  constructor(barbaz: BazService){
    this.barbaz = barbaz;
  }
}

@Component({
    selector: 'app',
    viewInjector: [BazService]
})
@View({
  template: `
    <foo #f></foo>
    <bar [prop]="f"></bar>
  `,
  directives: [FooComponent, BarComponent]
})
class AppComponent{}

bootstrap(AppComponent);

সরাসরি দেখুন


20
আমি এটি বের করেছিলাম। আপনি কেবল একটি পরিষেবা ইনজেক্ট করেন - 'অ্যাপ্লিকেশন'-এ। শিশু কনস্ট্রাক্টরগুলিতে প্যারামিটার যুক্ত করার সময় একই ঘটনাটি স্বয়ংক্রিয়ভাবে উত্তরাধিকার সূত্রে প্রাপ্ত হয়: আমি নতুন উপাদানগুলি তৈরি করে যা শিশু উপাদানগুলিতে অন্য একটি অ্যাপ্লিকেশনকারী যুক্ত করার ভুল করেছিলাম।
পার হর্নশেজ-শিয়েরবেক

4
@ আলেকজান্ডারক্রাশ আপনি কি নিজের উত্তর আপডেট করতে পারবেন? যেহেতু পরবর্তীতে আলফা সংস্করণগুলিতে (আলফা 30+) অ্যাপ্লিকেশনটিকে সরানো হয়েছে । সঠিক উত্তরটি, আপাতত ব্যবহার করা উচিত viewInjector
এরিক মার্টিনেজ

4
@ এরিকমার্টিনিজ ধন্যবাদ, উত্তর এবং প্লাঙ্কার আপডেট করা হয়েছে।
আলেকজান্ডার এরমোলভ

4
এটি কেন এবং কীভাবে কাজ করে তা বোঝার জন্য আকর্ষণীয় সংস্থান: blog.thoughtram.io/angular/2015/08/20/…
soyuka

4
আমার একই সমস্যা ছিল, কারণ আমি পরিষেবাটি মূল অ্যাপ্লিকেশনটিতে এবং নিজেই ব্যবহার করে থাকা উপাদানটিতে ইনজেকশন দিচ্ছিলাম providers: [MyService]। সরবরাহকারীদের সরানো, এটি অ্যাপ্লিকেশনটির একমাত্র উদাহরণ হয়ে উঠেছে
মাউফারিনেল্লি

43

@ মাউফারিনেল্লির মন্তব্যটি তার নিজের জবাবের দাবিদার কারণ এটি না হওয়া পর্যন্ত আমি @ আলেকসান্দার এরমোলভের উত্তর দিয়েও এই বিষয়টি নিয়ে আমার দেওয়ালের বিরুদ্ধে মাথা ঠাট্টা করেছিলাম।

সমস্যাটি হ'ল আপনি যখন এতে যুক্ত providersহন component:

@Component({
    selector: 'my-selector',
    providers: [MyService],
    template: `<div>stuff</div>`
})

এর ফলে আপনার পরিষেবার একটি নতুন দৃষ্টান্ত ইনজেকশনের করা ... বরং একটি থাকার চেয়ে Singleton

সুতরাং providers: [MyService]আপনার অ্যাপ্লিকেশনটিতে আপনার সমস্ত দৃষ্টান্ত ব্যতীত বাদ দিন moduleএবং এটি কার্যকর হবে!


4
কেবল একটি মন্তব্য, এটি কখনই সিঙ্গলটন নয় - এটি প্রায় একই উদাহরণটি প্রায় পাস করা হচ্ছে passed আপনি এখনও একটি নতুন উদাহরণের জন্য অনুরোধ করতে পারেন ...
পার হর্নশেজ-শিয়েরবেক

10

আপনাকে অবশ্যই @ কম্পোনেন্ট ডেকোরেটরের ইনপুট এবং আউটপুট ব্যবহার করতে হবে। উভয় ব্যবহারের সবচেয়ে প্রাথমিক উদাহরণ এখানে;

import { bootstrap } from 'angular2/platform/browser';
import { Component, EventEmitter } from 'angular2/core';
import { NgFor } from 'angular2/common';

@Component({
  selector: 'sub-component',
  inputs: ['items'],
  outputs: ['onItemSelected'],
  directives: [NgFor],
  template: `
    <div class="item" *ngFor="#item of items; #i = index">
      <span>{{ item }}</span>
      <button type="button" (click)="select(i)">Select</button>
    </div>
  `
})

class SubComponent {
  onItemSelected: EventEmitter<string>;
  items: string[];

  constructor() {
    this.onItemSelected = new EventEmitter();
  }

  select(i) {
    this.onItemSelected.emit(this.items[i]);
  }
}

@Component({
  selector: 'app',
  directives: [SubComponent],
  template: `
    <div>
      <sub-component [items]="items" (onItemSelected)="itemSelected($event)">
      </sub-component>
    </div>
  `
})

class App {
  items: string[];

  constructor() {
    this.items = ['item1', 'item2', 'item3'];
  }

  itemSelected(item: string): void {
    console.log('Selected item:', item);
  }
}

bootstrap(App);

7
আমদানি করার দরকার নেই ngFor,
রিচার্ড হ্যামিল্টন

7

মূল উপাদান টেমপ্লেটে:

<hero-child [hero]="hero">
</hero-child>

শিশু উপাদানগুলিতে:

@Input() hero: Hero;

সূত্র: https://angular.io/docs/ts/latest/cookbook/comp घटक- communication.html


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

আমি এই উপাদানটি অনেক উপাদানগুলির মধ্যে ডেটা ভাগ করার জন্য একটি বৃহত সমাধানে ব্যবহার করছি। আপনার অনেকগুলি শিশু থাকতে পারে এবং প্রত্যেকে একই বস্তু গ্রহণ করে। আপনি কি বলার আগে এটি করার চেষ্টা করেছিলেন যে এটি কাজ করে না?
অ্যালেক্সিস গামরা

হ্যা, আমি করেছিলাম . এটি কার্যকর হবে .... তবে কিছু সমস্যা সমাধানের জন্য কিছু "হ্যাকিং" দিয়ে। আপনার উত্তর কারও কাছে এটি ব্যবহার করার অনুমতি দেয় না।
স্যানস্লট

2

অনেক উপায় আছে। পিতা-মাতার এবং সন্তানের উপাদানগুলির মধ্যে বংশবিস্তার ব্যবহার করে এটি একটি উদাহরণ। এটি খুব দক্ষ।

আমি একটি উদাহরণ জমা দিয়েছি যা দুটি ফর্মের মধ্যে ডেটাবাইন্ডিংয়ের দুটি উপায়ের ব্যবহার দেখার অনুমতি দেয়। যদি কেউ প্লঙ্কার নমুনা সরবরাহ করতে পারে তবে এটি খুব সুন্দর হবে ;-)

আপনি কোনও পরিষেবা প্রদানকারী ব্যবহার করে অন্য কোনও উপায় সন্ধান করতে পারেন। রেফারেন্সের জন্য আপনার এই ভিডিওটিতে একবার নজর থাকতে পারে: ( কৌণিকের অংশগুলির মধ্যে ডেটা ভাগ করা )

mymodel.ts (ভাগ করার ডেটা)

// Some data we want to share against multiple components ...
export class mymodel {
    public data1: number;
    public data2: number;
    constructor(
    ) {
        this.data1 = 8;
        this.data2 = 45;
    }
}

মনে রাখবেন: এমন একটি পিতামাতার অবশ্যই থাকতে হবে যা "মমোডেল" সন্তানের উপাদানগুলিতে ভাগ করবে।

মূল উপাদান

import { Component, OnInit } from '@angular/core';
import { mymodel } from './mymodel';
@Component({
    selector: 'app-view',
    template: '<!-- [model]="model" indicates you share model to the child component -->
        <app-mychild [model]="model" >
        </app-mychild>'

        <!-- I add another form component in my view,
         you will see two ways databinding is working :-) -->
        <app-mychild [model]="model" >
        </app-mychild>',
})

export class MainComponent implements OnInit {
    public model: mymodel;
    constructor() {
        this.model = new mymodel();
    }
    ngOnInit() {
    }
}

শিশু উপাদান, mychild.componal.ts

import { Component, OnInit,Input } from '@angular/core';
import { FormsModule }   from '@angular/forms'; // <-- NgModel lives here
import { mymodel } from './mymodel';

@Component({
    selector: 'app-mychild',
    template: '
        <form #myForm="ngForm">
            <label>data1</label>
            <input type="number"  class="form-control" required id="data1 [(ngModel)]="model.data1" name="data1">
            <label>val {{model.data1}}</label>

            label>data2</label>
            <input  id="data2"  class="form-control" required [(ngModel)]="model.data2" name="data2" #data2="ngModel">
            <div [hidden]="data2.valid || data2.pristine"
                class="alert alert-danger">
                data2 is required
            </div>

            <label>val2 {{model.data2}}</label>
        </form>
    ',
})

export class MychildComponent implements OnInit {
    @Input() model: mymodel ;  // Here keywork @Input() is very important it indicates that model is an input for child component
    constructor() {
    }
    ngOnInit() {
    }
}

দ্রষ্টব্য: কিছু বিরল ক্ষেত্রে, এইচটিএমএল কোডটি বিশ্লেষণ করার সময় আপনার ত্রুটি হতে পারে, কারণ পৃষ্ঠার সূচনাতে মডেলটি ব্যবহারের জন্য "প্রস্তুত" নয়। এই ক্ষেত্রে, কোনও এনজিআই শর্ত সহ এইচটিএমএল কোডটি উপসর্গ করুন:

<div *ngIf="model"> {{model.data1}} </div>

1

এটি নির্ভর করে, যদি কোনও সাধারণ কেস থাকে

ক) এ -> বি -> সি এ এর ​​দুটি সন্তানের বি এবং সি রয়েছে এবং আপনি যদি এ এবং বি বা এ এবং সি এর মধ্যে ডেটা ভাগ করতে চান তবে (ইনপুট / আউটপুট) ব্যবহার করুন

আপনি যদি বি এবং সি এর মধ্যে ভাগ করতে চান তবে আপনি (ইনপুট / আউটপুট) ব্যবহার করতে পারেন তবে এটি পরিষেবা ব্যবহার করার পরামর্শ দেওয়া হচ্ছে।

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

এটি ফ্লাক্স আর্কিটেকচার প্রয়োগ করে যা একটি ক্লায়েন্টের সাইড স্টোর তৈরি করে যার কোনও উপাদান সাবস্ক্রাইব করতে পারে এবং কোনও রেসের শর্ত না তৈরি করে আপডেট করতে পারে।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.