angular - অর্ডার বাই পাইপ ইস্যু




angular2-template angular-pipe (11)

আমি এই কোডটি Angualr 1 থেকে Angular 2 তে অনুবাদ করতে পারছি না:

ng-repeat="todo in todos | orderBy: 'completed'"

থিয়েরি টেম্পিলারের উত্তর অনুসরণ করে আমি এটি করেছি:

উপাদান টেমপ্লেট:

*ngFor="#todo of todos | sort"

উপাদান কোড:

@Component({
    selector: 'my-app',
    templateUrl: "./app/todo-list.component.html",
    providers: [TodoService],
    pipes: [ TodosSortPipe ]

})

পাইপ কোড:

import { Pipe } from "angular2/core";
import {Todo} from './todo';

@Pipe({
  name: "sort"
})
export class TodosSortPipe {
  transform(array: Array<Todo>, args: string): Array<Todo> {
    array.sort((a: any, b: any) => {
      if (a < b) {
        return -1;
      } else if (a > b) {
        return 1;
      } else {
        return 0;
      }
    });
    return array;
  }
}

আমি সম্পত্তির দ্বারা Todo এর একটি অ্যারে বাছাই করার চেষ্টা করছি। প্রথমে todo.completed = false এবং তারপরে todo.complete = true

transform পদ্ধতি এবং সেই পদ্ধতিতে এবং sort পদ্ধতিতে কীভাবে আর্গুমেন্টগুলি পাস করতে হয় তা আমি খুব ভাল করে বুঝতে পারি না।

আর্গুমেন্ট কি args: string আর্গুমেন্ট? a এবং b কী এবং কোথা থেকে আসে?


অ্যাঙ্গুলার 2 এর বর্তমান সংস্করণে অর্ডারবাই এবং অ্যারেসোর্ট পাইপগুলি সমর্থিত নয়। এর জন্য আপনাকে কিছু কাস্টম পাইপ লিখতে / ব্যবহার করতে হবে।


আপনি এটি বস্তুর জন্য ব্যবহার করতে পারেন:

@Pipe({
  name: 'sort',
})
export class SortPipe implements PipeTransform {

  transform(array: any[], field: string): any[] {
    return array.sort((a, b) => a[field].toLowerCase() !== b[field].toLowerCase() ? a[field].toLowerCase() < b[field].toLowerCase() ? -1 : 1 : 0);
  }

}

আপনি কৌণিক দিয়ে লোডাশ ব্যবহার করার পরামর্শ দিন, তারপরে আপনার পাইপটি হবে:

import {Pipe, PipeTransform} from '@angular/core';
import * as _ from 'lodash'
@Pipe({
    name: 'orderBy'
})
export class OrderByPipe implements PipeTransform {

    transform(array: Array<any>, args?: any): any {
        return _.sortBy(array, [args]);
    }

}

এবং এটি এইচটিএমএলের মতো ব্যবহার করুন

*ngFor = "#todo of todos | orderBy:'completed'"

এবং আপনার মডিউলটিতে পাইপ যুক্ত করতে ভুলবেন না

@NgModule({
    ...,
    declarations: [OrderByPipe, ...],
    ...
})

আপনি যে কোনও ক্ষেত্রে এটি পাস করার জন্য এটি কাজ করবে। ( গুরুত্বপূর্ণ: এটি কেবল বর্ণানুক্রমিক অর্ডার করবে তাই আপনি যদি কোনও তারিখ পাস করেন তবে এটি এটিকে বর্ণমালা হিসাবে আদেশ করবে যেমন তারিখ নয়)

/*
 *      Example use
 *      Basic Array of single type: *ngFor="let todo of todoService.todos | orderBy : '-'"
 *      Multidimensional Array Sort on single column: *ngFor="let todo of todoService.todos | orderBy : ['-status']"
 *      Multidimensional Array Sort on multiple columns: *ngFor="let todo of todoService.todos | orderBy : ['status', '-title']"
 */

import {Pipe, PipeTransform} from "@angular/core";

@Pipe({name: "orderBy", pure: false})
export class OrderByPipe implements PipeTransform {

    value: string[] = [];

    static _orderByComparator(a: any, b: any): number {

        if (a === null || typeof a === "undefined") { a = 0; }
        if (b === null || typeof b === "undefined") { b = 0; }

        if (
            (isNaN(parseFloat(a)) ||
            !isFinite(a)) ||
            (isNaN(parseFloat(b)) || !isFinite(b))
        ) {
            // Isn"t a number so lowercase the string to properly compare
            a = a.toString();
            b = b.toString();
            if (a.toLowerCase() < b.toLowerCase()) { return -1; }
            if (a.toLowerCase() > b.toLowerCase()) { return 1; }
        } else {
            // Parse strings as numbers to compare properly
            if (parseFloat(a) < parseFloat(b)) { return -1; }
            if (parseFloat(a) > parseFloat(b)) { return 1; }
        }

        return 0; // equal each other
    }

    public transform(input: any, config = "+"): any {
        if (!input) { return input; }

        // make a copy of the input"s reference
        this.value = [...input];
        let value = this.value;
        if (!Array.isArray(value)) { return value; }

        if (!Array.isArray(config) || (Array.isArray(config) && config.length === 1)) {
            let propertyToCheck: string = !Array.isArray(config) ? config : config[0];
            let desc = propertyToCheck.substr(0, 1) === "-";

            // Basic array
            if (!propertyToCheck || propertyToCheck === "-" || propertyToCheck === "+") {
                return !desc ? value.sort() : value.sort().reverse();
            } else {
                let property: string = propertyToCheck.substr(0, 1) === "+" || propertyToCheck.substr(0, 1) === "-"
                    ? propertyToCheck.substr(1)
                    : propertyToCheck;

                return value.sort(function(a: any, b: any) {
                    let aValue = a[property];
                    let bValue = b[property];

                    let propertySplit = property.split(".");

                    if (typeof aValue === "undefined" && typeof bValue === "undefined" && propertySplit.length > 1) {
                        aValue = a;
                        bValue = b;
                        for (let j = 0; j < propertySplit.length; j++) {
                            aValue = aValue[propertySplit[j]];
                            bValue = bValue[propertySplit[j]];
                        }
                    }

                    return !desc
                        ? OrderByPipe._orderByComparator(aValue, bValue)
                        : -OrderByPipe._orderByComparator(aValue, bValue);
                });
            }
        } else {
            // Loop over property of the array in order and sort
            return value.sort(function(a: any, b: any) {
                for (let i = 0; i < config.length; i++) {
                    let desc = config[i].substr(0, 1) === "-";
                    let property = config[i].substr(0, 1) === "+" || config[i].substr(0, 1) === "-"
                        ? config[i].substr(1)
                        : config[i];

                    let aValue = a[property];
                    let bValue = b[property];

                    let propertySplit = property.split(".");

                    if (typeof aValue === "undefined" && typeof bValue === "undefined" && propertySplit.length > 1) {
                        aValue = a;
                        bValue = b;
                        for (let j = 0; j < propertySplit.length; j++) {
                            aValue = aValue[propertySplit[j]];
                            bValue = bValue[propertySplit[j]];
                        }
                    }

                    let comparison = !desc
                        ? OrderByPipe._orderByComparator(aValue, bValue)
                        : -OrderByPipe._orderByComparator(aValue, bValue);

                    // Don"t return 0 yet in case of needing to sort by next property
                    if (comparison !== 0) { return comparison; }
                }

                return 0; // equal each other
            });
        }
    }
}

আমি একটি অর্ডারবাই পাইপ তৈরি করেছি যা আপনার প্রয়োজন অনুযায়ী করে। এটি পাশাপাশি প্রচুর পরিমাণে অবজেক্টের একাধিক কলামে বাছাই করতে সক্ষম হয় supports

<li *ngFor="#todo in todos | orderBy : ['completed']">{{todo.name}} {{todo.completed}}</li>

এই পাইপটি পৃষ্ঠাটি রেন্ডার করার পরে অ্যারেতে আরও আইটেম যুক্ত করার অনুমতি দেয় এবং গতি অনুসারে আপডেটগুলি সহ অ্যারেটিকে সাজান।

আমি এখানে প্রক্রিয়া সম্পর্কে একটি লেখার আছে

এবং এখানে একটি কার্যকারী ডেমো রয়েছে: http://fuelinteractive.github.io/fuel-ui/#/pipe/orderby এবং https://plnkr.co/edit/DHLVc0?p=info


এটি কৌণিক 4 অ্যাংুলারজেস অর্ডারবি পাইপের জন্য ভাল প্রতিস্থাপন। সহজ এবং ব্যবহার করা সহজ।

এটি আরও তথ্যের জন্য গিথুব ইউআরএল https://github.com/VadimDez/ngx-order-pipe

import { Pipe, PipeTransform } from '@angular/core';

@Pipe({
  name: 'orderBy'
})
export class OrderPipe implements PipeTransform {

  transform(value: any | any[], expression?: any, reverse?: boolean): any {
    if (!value) {
      return value;
    }

    const isArray = value instanceof Array;

    if (isArray) {
      return this.sortArray(value, expression, reverse);
    }

    if (typeof value === 'object') {
      return this.transformObject(value, expression, reverse);
    }

    return value;
  }

  /**
   * Sort array
   *
   * @param value
   * @param expression
   * @param reverse
   * @returns {any[]}
   */
  private sortArray(value: any[], expression?: any, reverse?: boolean): any[] {
    const isDeepLink = expression && expression.indexOf('.') !== -1;

    if (isDeepLink) {
      expression = OrderPipe.parseExpression(expression);
    }

    let array: any[] = value.sort((a: any, b: any): number => {
      if (!expression) {
        return a > b ? 1 : -1;
      }

      if (!isDeepLink) {
        return a[expression] > b[expression] ? 1 : -1;
      }

      return OrderPipe.getValue(a, expression) > OrderPipe.getValue(b, expression) ? 1 : -1;
    });

    if (reverse) {
      return array.reverse();
    }

    return array;
  }


  /**
   * Transform Object
   *
   * @param value
   * @param expression
   * @param reverse
   * @returns {any[]}
   */
  private transformObject(value: any | any[], expression?: any, reverse?: boolean): any {
    let parsedExpression = OrderPipe.parseExpression(expression);
    let lastPredicate = parsedExpression.pop();
    let oldValue = OrderPipe.getValue(value, parsedExpression);

    if (!(oldValue instanceof Array)) {
      parsedExpression.push(lastPredicate);
      lastPredicate = null;
      oldValue = OrderPipe.getValue(value, parsedExpression);
    }

    if (!oldValue) {
      return value;
    }

    const newValue = this.transform(oldValue, lastPredicate, reverse);
    OrderPipe.setValue(value, newValue, parsedExpression);
    return value;
  }

  /**
   * Parse expression, split into items
   * @param expression
   * @returns {string[]}
   */
  private static parseExpression(expression: string): string[] {
    expression = expression.replace(/\[(\w+)\]/g, '.$1');
    expression = expression.replace(/^\./, '');
    return expression.split('.');
  }

  /**
   * Get value by expression
   *
   * @param object
   * @param expression
   * @returns {any}
   */
  private static getValue(object: any, expression: string[]) {
    for (let i = 0, n = expression.length; i < n; ++i) {
      const k = expression[i];
      if (!(k in object)) {
        return;
      }
      object = object[k];
    }

    return object;
  }

  /**
   * Set value by expression
   *
   * @param object
   * @param value
   * @param expression
   */
  private static setValue(object: any, value: any, expression: string[]) {
    let i;
    for (i = 0; i < expression.length - 1; i++) {
      object = object[expression[i]];
    }

    object[expression[i]] = value;
  }
}

প্যাকেজ.জসনে, এর মতো কিছু যুক্ত করুন (এই সংস্করণটি কৌনিক 2 এর জন্য ঠিক আছে):

  "ngx-order-pipe": "^1.1.3",

আপনার টাইপ স্ক্রিপ্ট মডিউলে (এবং অ্যারে আমদানি করে):

  import { OrderModule } from 'ngx-order-pipe';

যেহেতু আমরা জানি ফিল্টার এবং অর্ডার দ্বারা আংগুলার 2 থেকে অপসারণ করা হয়েছে এবং আমাদের নিজস্ব লেখার দরকার আছে, এখানে plunker এবং বিস্তারিত নিবন্ধের জন্য একটি ভাল উদাহরণ

এটি উভয় ফিল্টার পাশাপাশি অর্ডারবাই ব্যবহার করে, এখানে অর্ডার পাইপের কোড রয়েছে

import { Pipe, PipeTransform } from '@angular/core';    
@Pipe({  name: 'orderBy' })
export class OrderrByPipe implements PipeTransform {

  transform(records: Array<any>, args?: any): any {       
    return records.sort(function(a, b){
          if(a[args.property] < b[args.property]){
            return -1 * args.direction;
          }
          else if( a[args.property] > b[args.property]){
            return 1 * args.direction;
          }
          else{
            return 0;
          }
        });
    };
 }

আপডেট করা অর্ডারবাইপাইপ: স্ট্রিংগুলি বাছাইয়ের জন্য নির্দিষ্ট নয়।

অর্ডারবাইপাইপ শ্রেণি তৈরি করুন:

import { Pipe, PipeTransform } from "@angular/core";
@Pipe( {
name: 'orderBy'
} )
export class OrderByPipe implements PipeTransform {
transform( array: Array<any>, orderField: string, orderType: boolean ): Array<string> {
    array.sort( ( a: any, b: any ) => {
        let ae = a[ orderField ];
        let be = b[ orderField ];
        if ( ae == undefined && be == undefined ) return 0;
        if ( ae == undefined && be != undefined ) return orderType ? 1 : -1;
        if ( ae != undefined && be == undefined ) return orderType ? -1 : 1;
        if ( ae == be ) return 0;
        return orderType ? (ae.toString().toLowerCase() > be.toString().toLowerCase() ? -1 : 1) : (be.toString().toLowerCase() > ae.toString().toLowerCase() ? -1 : 1);
    } );
    return array;
  }
}

আপনার নিয়ামক মধ্যে:

@Component({
pipes: [OrderByPipe]
})

বা আপনার মধ্যে

 declarations: [OrderByPipe]

আপনার এইচটিএমএলে:

<tr *ngFor="let obj of objects | orderBy : ObjFieldName: OrderByType">

ObjFieldName: আপনি বাছাই করতে চান বস্তুর নাম;

অর্ডারবাইটাইপ: বুলিয়ান; সত্য: অবতরণ ক্রম; মিথ্যা: আরোহী;


কৌণিক জেএসে অর্ডারবাই পাইপ সমর্থন করবে তবে কৌণিক (উচ্চতর সংস্করণ) সমর্থন করবে না । পারফরম্যান্সের গতি অচল করার জন্য তিনি আলোচিত বিশদটি আবিষ্কার করুন।

https://angular.io/guide/pipes#appendix-no-filterpipe-or-orderbypipe


Component template:
todos| sort: ‘property’:’asc|desc’

Pipe code:

import { Pipe,PipeTransform  } from "angular/core";
import {Todo} from './todo';

@Pipe({
  name: "sort"
})
export class TodosSortPipe implements PipeTransform {
  transform(array: Array<Todo>, args: string): Array<Todo> {
    array.sort((a: any, b: any) => {
      if (a < b) {
        return -1;
      } else if (a > b) {
        return 1;
      } else {`enter code here`
        return 0;
      }
    });
    return array;
  }
}




angular-pipe