Denetleyicideki bir forma erişebilir miyim?


152

Şu anda aşağıdakileri kullanıyorum.

$scope.$$childHead.customerForm[firstName], Böylece:

<form name="customerForm">
  <input type="text" name="firstName" 
         ng-model="data.customer.firstName" 
         tabindex="1"  
         ng-disabled="!data.editable" 
         validationcustomer />
</form>

Ancak bu yalnızca Chrome'da çalışır. Şimdi aşağıdakileri denedim:

$scope.editCustomerForm[firstName], Böylece:

<form name="customerForm" ng-model="editCustomerForm">
  <input type="text" name="firstName" 
         ng-model="data.customer.firstName" tabindex="1"  
         ng-disabled="!data.editable" 
         validationcustomer />
</form>

Hangi işe yaramaz. Formumun bir Temel Sekmesi içinde olduğunu unutmayın. Nasıl erişebilirim firstName?

DÜZENLEME : Görünüşe göre Vakıf Sekmesi içerisine formeklenmez scope.

Bunun için bir çözümü olan var mı?

Yanıtlar:


210

Diğer yorumlarda ima rağmen Ben "Controller As" sözdizimini kullananlar için biraz heceleyeceğini düşündüm:

<div ng-controller="MyController as ctrl">

<form name="ctrl.myForm">
    ...inputs
    Dirty? {{ctrl.myForm.$dirty}}

    <button ng-click="ctrl.saveChanges()">Save</button>
</form>

</div>

Daha sonra FormController kodunuzda aşağıdaki gibi erişebilirsiniz:

function MyController () {
    var vm = this;
    vm.saveChanges = saveChanges;

    function saveChanges() {

       if(vm.myForm.$valid) { 
            // Save to db or whatever.
            vm.myForm.$setPristine();
       }
}

Görebildiğim kadarıyla, şablona maruz kalmaz gibi şablon "saveChanges" yöntemini çağıramaz
Spock

2
"SaveChanges" yöntemi, javascript 3 satırında maruz veya yanlış anlıyor musunuz?
slopapa

3
bence daha temiz olan tüm $ kapsamını enjekte etmekten kaçınabileceğiniz anlamına gelir
72GM

2
Bunu yasemin içinde nasıl test edersiniz? Benim spec, vm.myForm undefined
bahrieinn

1
Bu, bileşen ve es6 yapmanın yolu olan 1.5.X için resmi dokümanlarda belirtilmelidir. teşekkür ederim efendim
MatanCo

91

Formu, üst denetleyicide tanımlanan bir nesneye ekleyebilirsiniz. Böylece formunuza çocuk kapsamından bile ulaşabilirsiniz.

Ebeveyn denetleyicisi

$scope.forms = {};

Alt kapsamdaki bazı şablonlar

<form name="forms.form1">
</form>

Sorun form denetleyicisi kodlama yürütüldüğü anda tanımlanması gerekmez olmasıdır. Yani böyle bir şey yapmalısın

$scope.$watch('forms.form1', function(form) {
  if(form) {
    // your code...
  }
});

10
Ben var watcher = $scope.$watchersaatin bağlantısını kesmek için watcher () excute istiyorsunuz if deyimi ve içinde kullanmanızı öneririm . Bu, 1 kez izler, böylece ayarlandıktan sonra her bir özeti
izlemezsiniz

91

Formu doğrulama amacıyla denetleyiciye iletmek istiyorsanız, gönderimi işleyen yönteme bağımsız değişken olarak iletebilirsiniz. Form adını kullanın, böylece orijinal soru için şöyle bir şey olacaktır:

<button ng-click="submit(customerForm)">Save</button>

13
Formunuz / adlandırılmış buna benzer tanımlanır diyorsan, gelecek okuyucular için netleştirmek için <form name="myform"></form>, hatta <div ng-form name="myform"></div>daha sonra tıklama etkinliği olarak aşağıdaki şöyle olacaktır: ng-click="submit(myform)". Sonra gibi tıklama işlevi Açısal form nesnesi erişebilirsiniz: $scope.submit = function (form) { if (form.$valid) {vb
Matty j

Burada bir sorun buluyorum - diyelim ki formda bir açılır liste var. Yukarıdaki yöntemi kullanmak bana ihtiyacım olan kesin değeri değil, sadece görünüm değerini verir. Yoksa yanlış bir şey mi yapıyorum, bir keman ekleyeceğim.
swateek

82

Bir cevap için biraz geç ama aşağıdaki seçenekle geldi. Benim için çalışıyor ama doğru yol olup olmadığından emin değilim.

Bence bunu yapıyorum:

<form name="formName">
    <div ng-init="setForm(formName);"></div>
</form>

Ve denetleyicide:

$scope.setForm = function (form) {
    $scope.myForm = form;
}

Bunu yaptıktan sonra formumu kontrolör değişkenimde aldım. $scope.myForm


1
Buna ekleyeceğim tek şey, bunun formun altında olduğundan emin olmaktır.
smb

<Div ng-init = "setForm (formName);"> </div> konumu önemli değildir. Sadece formda olmasına dikkat edin.
waqas

1
iyi, ama daha basit bir çözümü tercih ederim: ng-init = "$ parent.myForm = formName" Denetleyiciyi değiştirme ihtiyacı olmadan Not: yukarıdaki çözümün aksine sadece doğrudan kontrolörle çalışıyor
mastilver

Diğer yöntemleri denedikten sonra, buna karar verdim çünkü nameözniteliğin tam olarak olmasını istediğim şey olmasına izin veriyor . Diğer kukla nesne çözümleriyle ilgili sorun, bu bileşenin ng formlu başka bir bileşende kullanılması, diğer ng formunun bu form adını tam anlamıyla kullanmasıdır. Yani "dummy.myForm" bir dize değişmez (yuvalanmış özellikleri) adı olan bir alana sahip olacak, bu kabul edilemez buldum.
Fesleğen

Denedim ve birçok kez controllerAs sözdizimi ($ mdDialog ile çalışıyorum) kullanmak için başarısız oldu. Sonunda buna yerleşti ve harika bir iş çıkardı. Yalnızca not, denetleyici ilk kez çalıştırıldığında form kullanılamadığından herhangi bir denetleyici başlatma işleminin $ zaman aşımı üzerinde çalıştırılması gerektiğidir
Peter Nixey

22

Denetleyicinizdeki forma erişebilmek için, onu sahte bir kapsam nesnesine eklemeniz gerekir.

Gibi bir şey $scope.dummy = {}

Durumunuz için bu şu anlama gelir:

<form name="dummy.customerForm">

Denetleyicinizde forma aşağıdaki yollarla erişebilirsiniz:

$scope.dummy.customerForm

ve bunun gibi şeyler yapabilirsiniz

$scope.dummy.customerForm.$setPristine()

WIKI BAĞLANTISI

Bir '.' modellerinizde prototip mirasın oyunda olduğundan emin olursunuz. Yani, kullanmak <input type="text" ng-model="someObj.prop1">yerine<input type="text" ng-model="prop1">

Gerçekten bir ilkel kullanmak istiyorsanız / gerekiyorsa, iki geçici çözüm vardır:

1. $ parent.parentScopeProperty öğesini alt kapsamda kullanın. Bu, çocuk kapsamının kendi mülkünü yaratmasını önleyecektir. 2.Veli kapsamındaki bir işlevi tanımlayın ve çocuktan çağırın, ilkel değeri ebeveyne kadar geçirin (her zaman mümkün değildir)


Form bağlamayı tanımlamak için etkili alan nerede?
Gus Crawford

form öğesinin üzerinde bir koşul olması durumunda dummy.customerForm, koşullar ng-ifkarşılanıncaya kadar tanımlanamayacağından bahsetmeye değerng-if
haxxxton

22

Bu cevap biraz geç, ama her şeyi çok daha kolay hale getiren bir çözüm buldum.

ControllerAs sözdizimini kullanıyorsanız, form adını doğrudan denetleyicinize atayabilir ve daha sonra "this" değişkeninizden referans alabilirsiniz. İşte benim kodda nasıl yaptım:

Denetleyiciyi ui-yönlendirici ile yapılandırdım (ancak HTML'de bile doğrudan böyle bir şeyle istediğiniz gibi yapabilirsiniz <div ng-controller="someController as myCtrl">) Bir ui-yönlendirici yapılandırmasında böyle görünebilir:

views: {
            "": {
                templateUrl: "someTemplate.html",
                controller: "someController",
                controllerAs: "myCtrl"
            }
       }

ve ardından HTML'de form adını "controllerAs" olarak ayarlamanız yeterlidir: "name" şöyle:

<ng-form name="myCtrl.someForm">
    <!-- example form code here -->
    <input name="firstName" ng-model="myCtrl.user.firstName" required>
</ng-form>

şimdi kumandanızın içinde bunu yapabilirsiniz:

angular
.module("something")
.controller("someController",
    [
       "$scope",
        function ($scope) {
            var vm = this;
            if(vm.someForm.$valid){
              // do something
            }
    }]);

2
Bu çoğunlukla diğer bazı cevapların önerdiği teknikle aynı olsa da, en iyi varyasyondur ve kabul edilen cevap olmalıdır, özellikle de herkes zaten kontrolör kullandığından.
Noktalı virgül

6

Evet, denetleyicideki bir forma erişebilirsiniz ( dokümanlarda belirtildiği gibi ).

Formunuz edildiğinde hariç değil kontrolör kapsamında tanımlanan ve bunun yerine bir çocuk kapsamda tanımlanmıştır.

Temel olarak ng-if, ng-repeatveya gibi bazı açısal direktifler ng-includeyalıtılmış bir çocuk kapsamı yaratacaktır. scope: {}Tanımlanmış bir özelliğe sahip herhangi bir özel direktif de öyle . Muhtemelen, temel bileşenleriniz de sizin yolunuzda.

Etiketin ng-ifetrafına basit bir giriş yaparken aynı sorunu yaşadım <form>.

Daha fazla bilgi için şunlara bakın:

Not: Sorunuzu yeniden yazmanızı öneririm. Sorunuzun cevabı evet, ancak sorununuz biraz farklı:

Denetleyiciden alt kapsamdaki bir forma erişebilir miyim?

Cevap sadece şöyle olur: hayır .


... formlarınızı ve denetleyicinizi @ondrs yanıtında ( $scope.forms = {}ve kullanarak name="forms.form1") açıklandığı gibi ayarlamadıysanız
marapet

Lütfen KhalilRavanna'nın hemen üstündeki cevaba bakınız. Forma $ scope.formName adresinden erişebilirsiniz. Çalışan bir örnek sunuyor
micbblu

3

ng-model="$ctrl.formName"formunuza öznitelik ekleyin ve sonra denetleyicide forma denetleyicinizin içinde bir nesne olarak erişebilirsiniz.this.formName


0

Kesinlikle bec kapsamındaki forma erişemezsiniz. yaratılmaz. Html şablonundan DOM denetleyici yapıcı gibi biraz yavaş yüklenir. çözüm, DOM yüklenene ve tüm kapsam tanımlanana kadar izlemektir!

denetleyicide:

$timeout(function(){
    console.log('customerForm:', $scope.customerForm);
    // everything else what you need
});
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.