Pertanyaan Apa perbedaan antara '@' dan '=' dalam lingkup direktif di AngularJS?


Saya telah membaca dokumentasi AngularJS pada topik dengan hati-hati, dan kemudian mengutak-atiknya dengan arahan. Ini dia biola.

Dan berikut ini beberapa cuplikan yang relevan:

  • Dari HTML:

    <pane bi-title="title" title="{{title}}">{{text}}</pane>
    
  • Dari direktif panel:

    scope: { biTitle: '=', title: '@', bar: '=' },
    

Ada beberapa hal yang tidak saya dapatkan:

  • Mengapa saya harus menggunakannya "{{title}}" dengan '@' dan "title" dengan '='?
  • Dapatkah saya juga mengakses ruang lingkup orang tua secara langsung, tanpa mendekorasi elemen saya dengan atribut?
  • Dokumentasi mengatakan "Seringkali diinginkan untuk mengirimkan data dari ruang lingkup yang terisolasi melalui ekspresi dan ke ruang lingkup orang tua", tapi itu tampaknya berfungsi dengan baik dengan bidirectional mengikat juga. Mengapa rute ekspresi lebih baik?

Saya menemukan biola lain yang menunjukkan solusi ekspresi juga: http://jsfiddle.net/maxisam/QrCXh/


996
2017-12-27 06:10


asal


Jawaban:


Mengapa saya harus menggunakan "{{title}}" dengan '@'dan "judul" dengan'='?

@ mengikat properti lingkup lokal / direktif ke nilai yang dievaluasi dari atribut DOM. Jika Anda menggunakan title=title1 atau title="title1", nilai atribut DOM "title" hanyalah string title1. Jika Anda menggunakan title="{{title}}", nilai atribut DOM "title" adalah nilai interpolasi dari {{title}}, maka string akan menjadi apa pun properti lingkup orangtua "judul" saat ini diatur ke. Karena nilai atribut selalu string, Anda akan selalu berakhir dengan nilai string untuk properti ini dalam lingkup direktif ketika menggunakan @.

= mengikat properti lingkup lokal / direktif ke properti lingkup orang tua. Jadi dengan =, Anda menggunakan nama properti model / ruang lingkup induk sebagai nilai atribut DOM. Anda tidak bisa menggunakannya {{}}dengan =.

Dengan @, Anda dapat melakukan hal-hal seperti title="{{title}} and then some" - {{title}} diinterpolasi, maka string "dan mereka beberapa" digabungkan dengannya. String gabungan terakhir adalah apa yang didapatkan properti lingkup lokal / direktif. (Kamu tidak bisa melakukan ini dengan =, saja @.)

Dengan @, Anda harus menggunakannya attr.$observe('title', function(value) { ... }) jika Anda perlu menggunakan nilai dalam fungsi tautan Anda (ing). Misalnya., if(scope.title == "...") tidak akan berfungsi seperti yang Anda harapkan. Perhatikan bahwa ini berarti Anda hanya dapat mengakses atribut ini secara asynchronous. Anda tidak perlu menggunakan $ mengamati () jika Anda hanya menggunakan nilai dalam template. Misalnya., template: '<div>{{title}}</div>'.

Dengan =, Anda tidak perlu menggunakan $ observasi.

Dapatkah saya juga mengakses ruang lingkup orang tua secara langsung, tanpa mendekorasi elemen saya dengan atribut?

Ya, tetapi hanya jika Anda tidak menggunakan ruang isolasi. Hapus baris ini dari arahan Anda

scope: { ... } 

dan kemudian arahan Anda tidak akan membuat ruang lingkup baru. Ini akan menggunakan ruang lingkup orang tua. Anda kemudian dapat mengakses semua properti lingkup induk langsung.

Dokumentasi mengatakan "Seringkali diinginkan untuk mengirim data dari ruang lingkup yang terisolasi melalui ekspresi dan ke ruang lingkup orang tua", tetapi tampaknya berfungsi dengan baik dengan bidirectional mengikat juga. Mengapa rute ekspresi lebih baik?

Ya, pengikatan dua arah memungkinkan lingkup lokal / direktif dan ruang lingkup orang tua untuk berbagi data. "Expression binding" memungkinkan direktif untuk memanggil ekspresi (atau fungsi) yang ditentukan oleh atribut DOM - dan Anda juga dapat mengirimkan data sebagai argumen ke ekspresi atau fungsi. Jadi, jika Anda tidak perlu berbagi data dengan orang tua - Anda hanya ingin memanggil fungsi yang didefinisikan dalam lingkup induk - Anda dapat menggunakan & sintaksis.

Lihat juga


1109
2017-12-28 01:15



Ada banyak jawaban yang bagus di sini, tetapi saya ingin menawarkan perspektif saya tentang perbedaan di antara keduanya @, =, dan & mengikat yang terbukti bermanfaat bagi saya.

Ketiga binding adalah cara-cara menyampaikan data dari ruang lingkup orang tua Anda ke lingkup terisolasi direktif Anda melalui atribut elemen:

  1. @ mengikat adalah untuk melewati string.      Dukungan string ini {{}} ekspresi untuk nilai interpolasi.      Sebagai contoh:      . Ekspresi interpolasi dievaluasi terhadap      ruang lingkup orang tua direktif.

  2. = mengikat adalah untuk mengikat model dua arah. Model dalam ruang lingkup orang tua      terkait dengan model dalam lingkup terisolasi direktif. Berubah menjadi      satu model mempengaruhi yang lain, dan sebaliknya.

  3. & mengikat adalah untuk melewatkan suatu metode ke dalam lingkup direktif Anda sehingga      itu bisa disebut dalam arahan Anda. Metodenya adalah pra-terikat      ruang lingkup orang tua direktif, dan mendukung argumen. Sebagai contoh jika metodenya adalah hello (nama) dalam ruang lingkup orang tua, maka di      Untuk melaksanakan metode dari dalam direktif Anda, Anda harus      panggil $ scope.hello ({name: 'world'})

Saya menemukan bahwa lebih mudah untuk mengingat perbedaan-perbedaan ini dengan mengacu pada lingkup pengikatan oleh deskripsi yang lebih singkat:

  • @  Atribut string yang mengikat
  • =  Model dua arah yang mengikat
  • &  Metode panggilan balik mengikat

Simbol-simbol juga membuatnya lebih jelas seperti apa variabel lingkup mewakili di dalam implementasi direktif Anda:

  • @  tali
  • =  model
  • &  metode

Dalam rangka kegunaan (untuk saya lagian):

  1. =
  2. @
  3. &

524
2018-02-03 23:30



Itu = berarti pengikatan bi-directional, jadi referensi ke variabel ke ruang lingkup orang tua. Ini berarti, ketika Anda mengubah variabel dalam direktif, itu akan diubah dalam ruang lingkup orang tua juga.

@ artinya variabel tersebut akan disalin (dikloning) ke dalam direktif.

Sejauh yang aku tahu, <pane bi-title="{{title}}" title="{{title}}">{{text}}</pane> harus bekerja juga. bi-title akan menerima nilai variabel cakupan induk, yang dapat diubah dalam direktif.

Jika Anda perlu mengubah beberapa variabel dalam lingkup induk, Anda bisa menjalankan fungsi pada ruang lingkup orang tua dari dalam direktif (atau meneruskan data melalui layanan).


60
2017-12-27 06:20



Jika Anda ingin melihat lebih banyak bagaimana ini bekerja dengan contoh hidup. http://jsfiddle.net/juanmendez/k6chmnch/

var app = angular.module('app', []);
app.controller("myController", function ($scope) {
    $scope.title = "binding";
});
app.directive("jmFind", function () {
    return {
        replace: true,
        restrict: 'C',
        transclude: true,
        scope: {
            title1: "=",
            title2: "@"
        },
        template: "<div><p>{{title1}} {{title2}}</p></div>"
    };
});

36
2017-11-21 23:19



@  dapatkan sebagai string

  • Ini tidak menciptakan binding apa pun. Anda hanya mendapatkan kata yang Anda sampaikan sebagai string

=  2 cara mengikat

  • perubahan yang dibuat dari pengontrol akan tercermin dalam referensi yang dipegang oleh arahan, dan sebaliknya

&Ini berperilaku agak berbeda, karena ruang lingkup mendapat fungsi itu mengembalikan objek yang dilewatkan masuk. Saya menganggap ini perlu untuk membuatnya bekerja. Biola harus menjelaskan hal ini.

  • Setelah memanggil fungsi pengambil ini, objek yang dihasilkan berperilaku sebagai berikut:
    • jika sebuah fungsi disahkan: maka fungsi dijalankan dalam induk (pengendali) penutupan saat dipanggil
    • jika sebuah tidak berfungsi disahkan di: cukup mendapatkan salinan lokal dari objek yang tidak memiliki binding


Biola ini harus menunjukkan bagaimana mereka bekerja. Bayar perhatian khusus pada fungsi ruang lingkup dengan get... dalam nama untuk semoga lebih memahami apa yang saya maksud &


36
2017-08-26 03:40



Ada tiga cara lingkup dapat ditambahkan dalam direktif:

  1. Ruang lingkup orang tua: Ini adalah warisan lingkup default.

Arahan dan ruang lingkup induknya (pengontrol / pengarahan di mana pun berada) adalah sama. Jadi setiap perubahan yang dilakukan pada variabel cakupan di dalam direktif direfleksikan dalam pengendali induk juga. Anda tidak perlu menentukan ini karena ini adalah default.

  1. Ruang lingkup anak: direktif menciptakan ruang lingkup anak yang mewarisi dari ruang lingkup orang tua jika Anda menetapkan variabel lingkup direktif sebagai benar.

Di sini, jika Anda mengubah variabel cakupan di dalam direktif, itu tidak akan mencerminkan dalam ruang lingkup orang tua, tetapi jika Anda mengubah properti dari variabel cakupan, yang tercermin dalam ruang lingkup orang tua, karena Anda benar-benar mengubah variabel cakupan dari orang tua .

Contoh,

app.directive("myDirective", function(){

    return {
        restrict: "EA",
        scope: true,
        link: function(element, scope, attrs){
            scope.somvar = "new value"; //doesnot reflect in the parent scope
            scope.someObj.someProp = "new value"; //reflects as someObj is of parent, we modified that but did not override.
        }
    };
});
  1. Ruang lingkup terisolasi: Ini digunakan ketika Anda ingin membuat ruang lingkup yang tidak mewarisi dari lingkup pengontrol.

Ini terjadi ketika Anda membuat plugin karena ini membuat direktif generik karena dapat ditempatkan di HTML apa pun dan tidak terpengaruh oleh ruang lingkup induknya.

Sekarang, jika Anda tidak ingin ada interaksi dengan lingkup induk, maka Anda bisa menentukan ruang lingkup sebagai objek kosong. seperti,

scope: {} //this does not interact with the parent scope in any way

Sebagian besar hal ini tidak terjadi karena kami memerlukan beberapa interaksi dengan ruang lingkup orang tua, jadi kami ingin beberapa nilai / perubahan untuk dilewati. Untuk alasan ini, kami menggunakan:

1. "@"   (  Text binding / one-way binding )
2. "="   ( Direct model binding / two-way binding )
3. "&"   ( Behaviour binding / Method binding  )

@ berarti bahwa perubahan dari ruang lingkup pengontrol akan tercermin dalam lingkup direktif tetapi jika Anda mengubah nilai dalam lingkup direktif, variabel cakupan pengontrol tidak akan terpengaruh.

@ selalu mengharapkan atribut yang dipetakan untuk menjadi ekspresi. Ini sangat penting; karena untuk membuat awalan "@", kita perlu membungkus nilai atribut di dalam {{}}.

= adalah bidirectional jadi jika Anda mengubah variabel dalam lingkup direktif, variabel lingkup pengontrol juga terpengaruh

& digunakan untuk mengikat metode scope controller sehingga jika diperlukan kita dapat memanggilnya dari direktif

Keuntungannya di sini adalah bahwa nama variabel tidak harus sama dalam lingkup pengontrol dan lingkup direktif.

Contoh, ruang lingkup direktif memiliki variabel "dirvar" yang sinkron dengan variabel "contVar" dari lingkup pengontrol. Ini memberikan banyak kekuatan dan generalisasi ke direktif sebagai satu pengendali dapat melakukan sinkronisasi dengan variabel v1 sementara pengontrol lain menggunakan direktif yang sama dapat meminta dirVar untuk menyinkronkan dengan variabel v2.

Di bawah ini adalah contoh penggunaan:

Arahan dan pengontrol adalah:

 var app = angular.module("app", []);
 app.controller("MainCtrl", function( $scope ){
    $scope.name = "Harry";
    $scope.color = "#333333";
    $scope.reverseName = function(){
     $scope.name = $scope.name.split("").reverse().join("");
    };
    $scope.randomColor = function(){
        $scope.color = '#'+Math.floor(Math.random()*16777215).toString(16);
    };
});
app.directive("myDirective", function(){
    return {
        restrict: "EA",
        scope: {
            name: "@",
            color: "=",
            reverse: "&"
        },
        link: function(element, scope, attrs){
           //do something like
           $scope.reverse(); 
          //calling the controllers function
        }
    };
});

Dan html (perhatikan differnce untuk @ dan =):

<div my-directive
  class="directive"
  name="{{name}}"
  reverse="reverseName()"
  color="color" >
</div>

Ini dia link ke blog yang menggambarkannya dengan baik.


33
2018-04-26 16:34



Cukup bisa kita gunakan: -

  1. @ : - untuk nilai-nilai String untuk mengikat data satu arah. dalam satu cara data yang mengikat Anda hanya bisa melewati nilai lingkup untuk direktif

  2. = : - untuk nilai objek untuk pengikatan data dua arah. dalam dua arah data yang mengikat Anda dapat mengubah nilai ruang lingkup dalam direktif serta di html juga.

  3. & : - untuk metode dan fungsi.

EDIT

Di dalam kita Komponen definisi untuk Versi sudut 1,5 Dan di atas
ada empat jenis bindings:

  1. =  Pengikatan data dua arah : - jika kita mengubah nilai, itu secara otomatis memperbarui
  2. <  satu cara mengikat : - ketika kita hanya ingin membaca parameter dari ruang lingkup orang tua dan tidak memperbaruinya.

  3. @ Ini untuk Parameter String

  4. & Ini untuk Callback jika komponen Anda perlu menghasilkan sesuatu ke ruang lingkup induknya


21
2017-08-29 10:44



Saya membuat file HTML kecil yang berisi kode Sudut yang menunjukkan perbedaan di antara mereka:

<!DOCTYPE html>
<html>
  <head>
    <title>Angular</title>
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular.min.js"></script>
  </head>
  <body ng-app="myApp">
    <div ng-controller="myCtrl as VM">
      <a my-dir
        attr1="VM.sayHi('Juan')" <!-- scope: "=" -->
        attr2="VM.sayHi('Juan')" <!-- scope: "@" -->
        attr3="VM.sayHi('Juan')" <!-- scope: "&" -->
      ></a>
    </div>
    <script>
    angular.module("myApp", [])
    .controller("myCtrl", [function(){
      var vm = this;
      vm.sayHi = function(name){
        return ("Hey there, " + name);
      }
    }])
    .directive("myDir", [function(){
      return {
        scope: {
          attr1: "=",
          attr2: "@",
          attr3: "&"
        },
        link: function(scope){
          console.log(scope.attr1);   // =, logs "Hey there, Juan"
          console.log(scope.attr2);   // @, logs "VM.sayHi('Juan')"
          console.log(scope.attr3);   // &, logs "function (a){return h(c,a)}"
          console.log(scope.attr3()); // &, logs "Hey there, Juan"
        }
      }
    }]);
    </script>
  </body>
</html>

11
2017-12-17 14:26



Itu = caranya adalah Pengikatan 2 arah, yang memungkinkan Anda memilikinya hidup perubahan di dalam arahan Anda. Ketika seseorang mengubah variabel itu keluar dari direktif, Anda akan mengubah data di dalam direktif Anda, tetapi @ caranya tidak dua cara mengikat. Ia bekerja seperti Teks. Anda mengikat sekali, dan Anda hanya akan memiliki nilainya.

Untuk membuatnya lebih jelas, Anda dapat menggunakan artikel hebat ini:

AngularJS Directive Scope '@' dan '='


7
2018-05-10 23:03



@ properti lingkup lokal digunakan untuk mengakses nilai string yang didefinisikan di luar direktif.

= Jika Anda perlu membuat pengikatan dua arah antara cakupan luar dan ruang lingkup isolasi direktif, Anda dapat menggunakan karakter =.

& properti cakupan lokal memungkinkan konsumen untuk mengarahkan fungsi yang dapat direktif.

Mohon periksa tautan di bawah ini yang memberi Anda pemahaman yang jelas dengan contoh-contoh. Saya merasa sangat berguna sehingga saya berpikir untuk membagikannya.

http://weblogs.asp.net/dwahlin/creating-custom-angularjs-directives-part-2-isolate-scope


4
2018-02-05 13:12