wake-up-neo.com

Warum diese NG-Show NG-Hide nicht funktioniert

Ich habe eine einfache App in AngularJS. Ich möchte Nachrichten dynamisch anzeigen, wenn eine Anforderung AJAX erfolgt. Leider immer in verstecktem Zustand und ich kann nicht herausfinden warum.

HTML:

<div ng-show="message">
    <h2>show</h2>
</div>

<div ng-hide="!message">
    <h2>Hide</h2>
</div>

AngularJS-Controller:

function merchantListController($scope, $http, $rootScope, $location, global) {
    $http({
        method: 'POST',
        url: global.base_url + '/merchant/list',
    }).success(function($data) {
        if ($data.status === 'success') {
            $scope.merchants = $data.data;

            $scope.$apply(function(){
                $scope.message = true;
            });
        }
    });
}

screenshot

16
Namal

Wahrscheinlich funktioniert das nicht, weil Sie einenewscope -Eigenschaft in einem untergeordneten Bereich erstellen, anstatt die message -Eigenschaft im Bereich von merchantListController wie erwartet zu überschreiben.

// The following assignment will create a 'message' variable 
// in the child scope which is a copy of the scope variable   
// in parent scope - effectively breaking two-way model binding.
$scope.message = true;

Stellen Sie zur Behebung dieses Problems sicher, dass Sie per reference an eine Eigenschaft in Ihrem Modell und nicht an eine Eigenschaft im Gültigkeitsbereich binden.

HTML

<div ng-show="my.message">
   <h2>show</h2>
</div>

<div ng-hide="!my.message">
   <h2>Hide</h2>
</div>

Controller

function merchantListController($scope, $http, $rootScope, $location, global) {

   // Initialize my model - this is important!
   $scope.my = { message: false };

   $http({
        method: 'POST',
        url: global.base_url + '/merchant/list',
    }).success(function($data) {

        if ($data.status === 'success') {
            $scope.merchants = $data.data;

            // modify the 'message' property on the model
            $scope.my.message   = true;
        }

    });
});

Erklärung

Der Grund dafür ist, dass das Modell my mit Bereichsvererbungsregeln aufgelöst wird. Wenn my im aktuellen Bereich nicht vorhanden ist, suchen Sie im übergeordneten Bereich nach my, bis er entweder gefunden wird oder die Suche bei $ rootScope stoppt. Sobald das Modell gefunden wurde, wird die message-Eigenschaft überschrieben. 

22
pixelbits

Die Logik zum Anzeigen/Verbergen ist falsch. Ändern Sie sie wie folgt: ng-hide = "message"

    <div ng-show="message">
       <h2>show</h2>
    </div>

   <div ng-hide="message">
       <h2>Hide</h2>
   </div>

ng-hide benötigt Variable, um sich auszublenden, ng-show braucht es, wenn angezeigt werden soll. Daher sind die Bedingungen ng-show = "message" & ng-hide = "! message" gleich. 

Versuchen Sie folgendes:

    <div ng-show="message">
       <h2>show</h2>
    </div>

   <div ng-show="!message">
       <h2>Hide</h2>
   </div>

Nur zum Testen ... ändern Sie Ihre http-Klasse folgendermaßen:

$http({
    method: 'POST',
    url: global.base_url + '/merchant/list',
}).success(function($data) {

            $scope.message   = true;
    }).error(function($data) {
            $scope.message   = false;
    });
8
harishr
Because you did a mistake...

ng-show="message" and ng-hide="!message" both points to the same value..

Correct it as..
<div **ng-show="message"**>
    <h2>show</h2>
</div>

<div **ng-hide="message"**>
    <h2>Hide</h2>
</div>

//or you can do in your way as...

<div **ng-show="message"**>
    <h2>show</h2>
</div>

<div **ng-show="!message"**>
    <h2>Hide</h2>
</div
1
Bunker Boy

Also, nachdem ich einige Zeit mit einer 2 Jahre alten Frage verbracht habe, werde ich hier etwas hinzufügen.

$scope.apply() ist nicht erforderlich und würde wahrscheinlich einen Fehler auslösen, der besagt, dass der Antrag bereits läuft. Wenn Sie es richtig machen, sollten Sie diese Funktion sehr selten oder nie aufrufen. Die Hauptanwendung wäre, wenn Sie Bibliotheken von Drittanbietern verwenden. Das Winkelmodul konnte nicht auf Änderungen achten oder sehen, was sie tun, und Sie müssen den Digest-Zyklus manuell auslösen.

Ich würde empfehlen, Variablen zu initialisieren, so dass Ihr Controller so aussehen würde (ich habe auch die http-Anfrage an einen Dienst extrahiert und then für die Behandlung von Antworten und Fehlern verwendet, da .success() veraltet ist):

function merchantService($http) {
    function post() {
    return $http.get('localhost');
    //Just a dummy $http request, instead of yours.
    //return $http.post(global.base_url + '/merchant/list');
  }

    /*  this is rather implicit, but if you are doing a service like this, 
        you can keep the functions "private" and export an object, that  
        contains the functions you wish to make "public" */

    return {
      post: post
  };
}

function merchantListController($scope, merchantService) {
    /* Initialize the variable, so ng-show and ng-hide 
       have something to work with in the beginning
       rather then just being undefined. */

    $scope.message = false;

    // call the post from the function
    merchantService.post()
  .then(function (response) {

    /* The first then() will hold the response
       if the request was OK */

    console.log(response);
    $scope.merchants = response.data;

    /* Since this then() will be triggered on a successful request
       we are safe to say $scope.message should now be true. */

    $scope.message = true;
  })
  .then(function (error) {

    // The second one is for the failed request.

    console.error(error);
  });
}

var app = angular.module('myApp', []);
app.controller('merchantListController', merchantListController);
app.factory('merchantService', merchantService);

Eine Arbeitsgeige finden Sie hier: https://jsfiddle.net/vnjbzf3o/4/

1
Alex Szabó

Die $ scope. $ Digest () - Funktion durchläuft alle Überwachungen im $ scope-Objekt und die zugehörigen untergeordneten $ scope-Objekte (sofern vorhanden). Wenn $ digest () die Uhren durchläuft, ruft es die Wertefunktion für jede Uhr auf. Wenn der von der value-Funktion zurückgegebene Wert sich von dem Wert unterscheidet, den er beim letzten Aufruf zurückgegeben hat, wird die Listener-Funktion für diese Überwachung aufgerufen.

Die Funktion $ digest () wird aufgerufen, wenn AngularJS dies für notwendig hält. Zum Beispiel, nachdem ein Button-Click-Handler ausgeführt wurde oder nachdem ein Aufruf von AJAX zurückgegeben wurde (nachdem die done ()/fail () - Callback-Funktion ausgeführt wurde).

In einigen Fällen kann es vorkommen, dass AngularJS die Funktion $ digest () nicht für Sie aufruft. Sie werden dies normalerweise feststellen, indem Sie feststellen, dass die Datenbindungen die angezeigten Werte nicht aktualisieren. Rufen Sie in diesem Fall $ scope. $ Digest () auf, und es sollte funktionieren. Oder Sie können vielleicht $ scope verwenden. $ Apply ()

Das kannst du so machen: 

HTML 

<div ng-hide="message"> <h2>show</h2> <div>

<div ng-hide="!message"> <h2>Hide</h2> </div>

JS

$scope.message = true;


function merchantListController($scope, $http, $rootScope, $location, global) {
$http({
    method: 'POST',
    url: global.base_url + '/merchant/list',
}).success(function($data) {
    if ($data.status === 'success') {
        $scope.merchants = $data.data;

        $scope.$apply(function(){
            $scope.message = false;
            $scope.$digest();
        });
    }
});
1
Amit Kumar

Zunächst ist der Aufruf von $ scope. $ Apply () nicht erforderlich. 

Wenn die Variable show nie angezeigt wird, bedeutet dies, dass $scope.message = true; nicht ausgeführt wird. Wenn es nicht ausgeführt wird, bedeutet dies, dass entweder die Anforderung AJAX nicht erfolgreich ist oder dass $data.status === 'success' niemals wahr ist.

Debuggen Sie Ihren Code, oder fügen Sie console.log () -Spuren hinzu, um die Werte Ihrer Variablen zu überprüfen und zu sehen, was ausgeführt wird und was nicht. Standardmäßige Debugging-Arbeit.

Stellen Sie Ihrer Datenvariablen auch kein $ voran. Der $ ist normalerweise für von Winkeln bereitgestellte Dienste reserviert.

0
JB Nizet