Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/jquery/73.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 这是使用延迟对象的正确方法吗?_Javascript_Jquery_Jquery Deferred - Fatal编程技术网

Javascript 这是使用延迟对象的正确方法吗?

Javascript 这是使用延迟对象的正确方法吗?,javascript,jquery,jquery-deferred,Javascript,Jquery,Jquery Deferred,我正在构建一个应用程序,需要列出产品的类别和子类别 当用户选择一个类别时,与该类别相关的子类别将通过ajax从服务器加载,但只有在以后没有加载时,才会从DOM加载 代码: 因为代码中到处都是回调,我决定使用jquerydeferred对象,但我不知道这是否是正确的实现。有人能告诉我,我做了正确的事情,还是应该做不同的事情?我看不出有什么明显的错误。总之,您正在以正确的方式使用延迟:抽象出您的方法可能具有的双重同步性。现在,也就是说,如果这是出现在我的代码库中的代码,我会这样写。要点是:不要在数组

我正在构建一个应用程序,需要列出产品的类别和子类别

当用户选择一个类别时,与该类别相关的子类别将通过ajax从服务器加载,但只有在以后没有加载时,才会从DOM加载

代码:


因为代码中到处都是回调,我决定使用jquerydeferred对象,但我不知道这是否是正确的实现。有人能告诉我,我做了正确的事情,还是应该做不同的事情?

我看不出有什么明显的错误。总之,您正在以正确的方式使用延迟:抽象出您的方法可能具有的双重同步性。现在,也就是说,如果这是出现在我的代码库中的代码,我会这样写。要点是:不要在数组中使用in,使用数组构建字符串,一致的命名和间距,以及其他一些简洁的JS首选项。这是品味的问题,否则,干得好:

(function() {
    var getSubCategories = function ( categoryId ) {
        categoryId = +categoryId;

        return $.Deferred( function ( dfd ) {

            var isLoaded = form.find( 'select.product-subcategories' )
                .map( function ( index, el ) {
                    if ( +$( this ).data( 'category' ) === categoryId ) {
                        return el;
                    }
                }),
                markup = [ ];

            if ( isLoaded.length ) {
                console.log( 'SubCategory loaded from DOM' );
                dfd.resolve( isLoaded );
            } else {
                markup.push( '<select data-category="' + categoryId +  '" class="product-subcategories">' );

                var request = $.ajax({
                    url: '/',
                    data: { categoryId: categoryId }    
                });

                request.done( function ( result ) {
                    //simulate success :X
                    result = {"status":1,"data":[{"name":"Sub-Category I","id":1},{"name":"Sub-Category II","id":2},{"name":"Sub-Category III","id":3}]};

                    var status = result.status,
                        data = result.data,
                        i = 0,
                        il = data.length,
                        current;

                    console.log( 'SubCategory loaded with Ajax' );

                    if ( status !== 1 || !data ) {
                        dfd.reject();
                        return;
                    }

                    for ( current = data[ i ]; i < il; i++ ) {
                        markup.push( '<option value="' + current.id + '">' );
                        markup.push( current.name + '</option>' );  
                    }

                    markup.push( '</select>' );

                    dfd.resolve( $( markup.join( '' ) ).hide().appendTo( form ) );
                });
            }

        }).promise();
    };

    var form = $( '#new-product-form' )
        .on( 'change', 'select.product-categories', function ( e ) {
            getSubCategories( $( this ).val() )
                .done( function( el ) {
                    form.find( 'select.product-subcategories' )
                        .not( el )
                            .hide()

                    el.show();
                });
        });
});

作为旁注,我只想指出,如果ajax请求失败,您不会有任何问题处理。在这种情况下,您需要拒绝,并确保编写失败方法。只是提醒一下。

我没有看到任何明显不正确的地方。总之,您正在以正确的方式使用延迟:抽象出您的方法可能具有的双重同步性。现在,也就是说,如果这是出现在我的代码库中的代码,我会这样写。要点是:不要在数组中使用in,使用数组构建字符串,一致的命名和间距,以及其他一些简洁的JS首选项。这是品味的问题,否则,干得好:

(function() {
    var getSubCategories = function ( categoryId ) {
        categoryId = +categoryId;

        return $.Deferred( function ( dfd ) {

            var isLoaded = form.find( 'select.product-subcategories' )
                .map( function ( index, el ) {
                    if ( +$( this ).data( 'category' ) === categoryId ) {
                        return el;
                    }
                }),
                markup = [ ];

            if ( isLoaded.length ) {
                console.log( 'SubCategory loaded from DOM' );
                dfd.resolve( isLoaded );
            } else {
                markup.push( '<select data-category="' + categoryId +  '" class="product-subcategories">' );

                var request = $.ajax({
                    url: '/',
                    data: { categoryId: categoryId }    
                });

                request.done( function ( result ) {
                    //simulate success :X
                    result = {"status":1,"data":[{"name":"Sub-Category I","id":1},{"name":"Sub-Category II","id":2},{"name":"Sub-Category III","id":3}]};

                    var status = result.status,
                        data = result.data,
                        i = 0,
                        il = data.length,
                        current;

                    console.log( 'SubCategory loaded with Ajax' );

                    if ( status !== 1 || !data ) {
                        dfd.reject();
                        return;
                    }

                    for ( current = data[ i ]; i < il; i++ ) {
                        markup.push( '<option value="' + current.id + '">' );
                        markup.push( current.name + '</option>' );  
                    }

                    markup.push( '</select>' );

                    dfd.resolve( $( markup.join( '' ) ).hide().appendTo( form ) );
                });
            }

        }).promise();
    };

    var form = $( '#new-product-form' )
        .on( 'change', 'select.product-categories', function ( e ) {
            getSubCategories( $( this ).val() )
                .done( function( el ) {
                    form.find( 'select.product-subcategories' )
                        .not( el )
                            .hide()

                    el.show();
                });
        });
});

作为旁注,我只想指出,如果ajax请求失败,您不会有任何问题处理。在这种情况下,您需要拒绝,并确保编写失败方法。请注意。

除了链接外,请在问题中包含相关代码。目的是尽可能保持自给自足。如果外部站点消失,问题仍然应该是相关的。@JamesMontagne请参见编辑。我会缓存延迟对象,并在每次后续更改中重新构建选项,以避免在非常大的类别/子类别情况下最终有大量隐藏元素,但除此之外,只要元素的数量不太大,你所拥有的就可以使用。除了链接外,请在问题中包含相关代码。目的是尽可能保持自给自足。如果外部站点消失,问题仍然应该是相关的。@JamesMontagne请参见编辑。我会缓存延迟对象,并在每次后续更改中重新构建选项,以避免在非常大的类别/子类别情况下最终有大量隐藏元素,但除此之外,只要元素的数量不太大,你所拥有的就可以工作。谢谢你的提醒。只有一个问题,在变量前面加一个加号可以将其转换为整数?使用JavaScript一元加号运算符可以尝试将一个值转换为一个数字(如果它还没有)。这很简单也很快:谢谢你的提醒。只有一个问题,在变量前面加一个加号可以将其转换为整数?使用JavaScript一元加号运算符可以尝试将一个值转换为一个数字(如果它还没有)。它既简单又快速:
(function() {
    var getSubCategories = function ( categoryId ) {
        categoryId = +categoryId;

        return $.Deferred( function ( dfd ) {

            var isLoaded = form.find( 'select.product-subcategories' )
                .map( function ( index, el ) {
                    if ( +$( this ).data( 'category' ) === categoryId ) {
                        return el;
                    }
                }),
                markup = [ ];

            if ( isLoaded.length ) {
                console.log( 'SubCategory loaded from DOM' );
                dfd.resolve( isLoaded );
            } else {
                markup.push( '<select data-category="' + categoryId +  '" class="product-subcategories">' );

                var request = $.ajax({
                    url: '/',
                    data: { categoryId: categoryId }    
                });

                request.done( function ( result ) {
                    //simulate success :X
                    result = {"status":1,"data":[{"name":"Sub-Category I","id":1},{"name":"Sub-Category II","id":2},{"name":"Sub-Category III","id":3}]};

                    var status = result.status,
                        data = result.data,
                        i = 0,
                        il = data.length,
                        current;

                    console.log( 'SubCategory loaded with Ajax' );

                    if ( status !== 1 || !data ) {
                        dfd.reject();
                        return;
                    }

                    for ( current = data[ i ]; i < il; i++ ) {
                        markup.push( '<option value="' + current.id + '">' );
                        markup.push( current.name + '</option>' );  
                    }

                    markup.push( '</select>' );

                    dfd.resolve( $( markup.join( '' ) ).hide().appendTo( form ) );
                });
            }

        }).promise();
    };

    var form = $( '#new-product-form' )
        .on( 'change', 'select.product-categories', function ( e ) {
            getSubCategories( $( this ).val() )
                .done( function( el ) {
                    form.find( 'select.product-subcategories' )
                        .not( el )
                            .hide()

                    el.show();
                });
        });
});