javascript - الزاوي واجهة المستخدم الزاوي لا يعالج وظيفة حل عند استخدام ميزة مزامنة/تنتظر؟




angularjs angular-ui-router (2)

لقد حاولت تقديم قالب معين يتعلق بحالة ومكون وفقا لهذه المقالة

في مشروعي قيد التشغيل تحت الخادم ديف كل شيء يعمل بشكل جيد وعند تنفيذ $state.go("home") يتم تحميل قالب المكون كيف أتوقع ولكن عندما أفعل ذلك في بيئة الاختبار، وهذا لا يعمل.

من قبل، في الاختبار، عند استخدام "الطريقة القديمة" باستخدام "قالب" بدلا من "مكون" مع جهاز التوجيه، تنفيذ $rootScope.$digest() كان كافيا لإضافة القالب داخل <div ui-view></div> ولكن باستخدام هذه الطريقة الجديدة هذا لا يعمل بعد الآن.

ما الخطأ الذي افعله؟

تحرير : لقد حاولت فهم المشكلة بعمق وأرى أن المشكلة تتعلق بطلب هتب الذي تم القيام به. ربما انها تتعلق بالطريقة التي وعدي يحل على رد الاستدعاء باستخدام غير متزامن / تنتظر. يرجى التحقق من الخدمة:

الخدمات

export class TodoService {
    constructor($http, BASE_URL) {
        this.http = $http;
        this.url = `${BASE_URL}/todos`
    }
    async getTodos() {
        const apiResponse = await this.http.get(this.url)
        return apiResponse.data.todos
    }
}

راوتر

import '@uirouter/angularjs'

export function routes($stateProvider, $locationProvider) {
    $locationProvider.html5Mode({
        enabled: true,
        requireBase: false,
        rewriteLinks: true,
    })

    $stateProvider
        .state("home", {
            url: "/",
            component: "todoList",
            resolve: {
                todosList: TodoService => TodoService.getTodos()
            }
        })
}

اختبار

import { routes } from "routes"
import { TodoListComponent } from "components/todoList.component"
import { TodoService } from "services/todo.service"

describe("TodoListComponent rendering and interaction on '/' base path", () => {
    let componentDOMelement
    let stateService

    beforeAll(() => {
        angular
            .module("Test", [
                "ui.router"
            ])
            .config(routes)
            .constant("BASE_URL", "http://localhost:5000/api")
            .component("todoList", TodoListComponent)
            .service("TodoService", TodoService)
            //I enable this for better logs about the problem
            .run(['$rootScope','$trace', function($rootScope, $trace) {
               $trace.enable("TRANSITION")
             }])
    })
    beforeEach(angular.mock.module("Test"))

    beforeEach(inject(($rootScope, $compile, $state, $httpBackend) => {
        //build the scene
        //1st render the root element of scene: We needs a router view for load the base path
        let scope = $rootScope.$new()
        componentDOMelement = angular.element("<div ui-view></div>")

        $compile(componentDOMelement)(scope)
        scope.$digest()
        
         document.body.appendChild(componentDOMelement[0]) //This is a hack for jsdom before the $rootScope.$digest() call
        //2nd let's create a fake server for intercept the http requests and fake the responses
        const todosResponse = require(`${__dirname}/../../stubs/todos_get.json`)
        $httpBackend
            .whenGET(/.+\/todos/)
            .respond((method, url, data, headers, params) => {
                return [200, todosResponse]
            })

        //3rd Let's generate the basic scenario: Go at home state ("/" path)
        $state.go("home")
        $rootScope.$digest()
        $httpBackend.flush()
    }))

    it("Should be render a list", () => {
        console.log("HTML rendered")
        console.log(document.querySelectorAll("html")[0].outerHTML)
    })
})

نتيجة هتمل التي لا يتم عرضها

<html>
<head>
<style type="text/css">
@charset "UTF-8";[ng\:cloak],[ng-cloak],[data-ng-cloak],[x-ng-cloak],.ng-cloak,.x-ng-cloak,.ng-hide:not(.ng-hide-animate) {
  display:none !important;
}
ng\:form{display:block;}.ng-animate-shim{visibility:hidden;}.ng-anchor{
  position:absolute;
}
</style>
</head>
<body><!-- uiView: -->
</body>
</html>

أيضا، تتبعت ستاتشانج قبل هتمل:

console.log node_modules/@uirouter/core/_bundles/ui-router-core.js:1276
    Transition #0-0: Started  -> "Transition#0( ''{} -> 'home'{} )"

console.log node_modules/@uirouter/core/_bundles/ui-router-core.js:1282
    Transition #1-0: Ignored  <> "Transition#1( ''{} -> 'home'{} )"

console.log node_modules/@uirouter/core/_bundles/ui-router-core.js:1313
    Transition #1-0: <- Rejected "Transition#1( ''{} -> 'home'{} )", reason: Transition Rejection($id: 0 type: 5, message: The transition was ignored, detail: "undefined")

أرى مشكلة في مرحلة انتقالية ولكن لم يتم إعطاء سبب.

================================================== ======================

تحرير 2 وأخيرا وجدنا المشكلة ولكن لا أستطيع معرفة المشكلة الحقيقية . لقد أنشأت فرعا في مشروعي لعرض المشكلة. هذا الأمر مرتبط async/await ميزة جافا سكريبت:

export class TodoService {
    constructor($http, BASE_URL) {
        this.http = $http;
        this.url = `${BASE_URL}/todos`
    }
    //Interchange the comment on the getTodos method and run `npm run tdd` for see the problem:
    //When async/await doesn't used, the html associated to the resolve in the
    // "/" route that used this service, the promise was resolved that expected.
    //The idea for this branch it's research about the problem and propose a way
    //for we can use async/await on the production code and on the testing environment
    async getTodos() {
        const apiResponse = await this.http.get(this.url)
        return apiResponse.data.todos
    }
    // getTodos() {
    //     return this.http.get(this.url).then(res => res.data.todos)
    // }
}

المستودع

لذا فإن أسئلتي الجديدة هي:

  • لماذا الطريقة التي يمكنني استخدام وظيفة متزامنة / تنتظر انها ليست متوافقة مع عزم جهاز التوجيه واجهة المستخدم على اختبار البيئة ولكن في رمز الإنتاج يعمل؟
  • ربما انها ذات الصلة إلى $ httpBackend.flush () استدعاء؟

تحرير 3 المسألة 3522 ذكرت في الزاوي أوي جهاز التوجيه المخزن


هذا هو مجرد تخمين متعلمين على أساس فهمي للطريقة resolve -ers العمل وما ngMock لا. في المثال الأول الخاص بك، resolve الخاص بك ل getTodos لا يعود حتى حل $http حل، وعند هذه النقطة كنت نتف قيمة من الاستجابة وإعادته. ومع ذلك، يتوقع حل- $q.Promise قيمة $q.Promise للاحتفاظ تقديم الموجه حتى يحل. في التعليمات البرمجية الخاصة بك، اعتمادا على كيفية انها ترانزبيلد، والمنتظر return الأرجح لا تنتج قيمة الحارس الصحيح، لذلك يتم التعامل معها مثل استجابة متزامنة.

طريقة واحدة لاختبار سيكون لطلب resolve -er في وحدة تحكم لمكون todolist الخاص بك وتفتيش القيمة. سوف أراهن انها ليست $q.Promise ، على الرغم من أنه قد يكون وعد الأصلي.

عند استخدام resolve ، على الرغم من مجرد سلسلة الوعد بإضافة then إعادته. سيقوم جهاز التوجيه بمعالجة بقية.

أو أفضل، والتبديل إلى مرئية! (/ لي بط الطماطم واردة)








async-await