问:
String Pattern Question - Core Java (repeatSeparator)
Write a Java function such that Given two strings, word and a separator, return a big string made of count occurences of the word, separated by the separator string.

```<code>repeatSeparator("Word", "X", 3) → "WordXWordXWord"
repeatSeparator("This", "And", 2) → "ThisAndThis"
repeatSeparator("This", "And", 1) → "This"
</code>```

My code is as below but is not working

```<code>public String repeatSeparator(String word, String sep, int count) {
    if(count == 1) {
        return word;
    }
    if(count > 1) {
        for (int i = 0; i < count-1; i++){
            word = word + sep + word;
        }
    }
   return word;
}
</code>```

Example Output ::

```<code>                                   Expected         Run                  Result
repeatSeparator("Word", "X", 3) → "WordXWordXWord" "WordXWordXWordXWord" X
</code>```

答:
```<code>public string doStuff(
    final String word,
    final String seperator,
    final int count)
{
    StringBuffer buffer = new StringBuffer();
    for (int index = 0; index < count; ++index)
    {
        if (buffer.length() > 0)
        {
            buffer.append(seperator);
        }

        buffer.append(word);
    }

    return buffer.toString();
}
</code>```

Body:
Write a Java function such that Given two strings, word and a separator, return a big string made of count occurences of the word, separated by the separator string.

repeatSeparator("Word", "X", 3) → "WordXWordXWord"
repeatSeparator("This", "And", 2) → "ThisAndThis"
repeatSeparator("This", "And", 1) → "This"

My code is as below but is not working

public String repeatSeparator(String word, String sep, int count) {
    if(count == 1) {
        return word;
    }
    if(count > 1) {
        for (int i = 0; i < count-1; i++){
            word = word + sep + word;
        }
    }
   return word;
}

Example Output ::

                                   Expected         Run                  Result
repeatSeparator("Word", "X", 3) → "WordXWordXWord" "WordXWordXWordXWord" X


来源: stackexchange

问:
BinaryFormatter Deserialisation throws exception when used through COM interop
I have to update some old applications (vb6) and I have been using COM interop to write the new code in c# (Visual Studio 2010). Its mostly worked OK but I have come across a problem and I am not sure what is causing it.

I use the following method to perform a deep copy of an object

```<code>    public static T CloneObject<T>(T source)
    {
        T destination = default(T);

        if (!typeof(T).IsSerializable)
        {
            throw new ArgumentException("The type must be serialisable.", "source");
        }

        if (Object.ReferenceEquals(source, null))
        {
            return default(T);
        }

        using (Stream ms = new MemoryStream())
        {
            BinaryFormatter formatter = new BinaryFormatter();
            formatter.Serialize(ms, source);
            ms.Position = 0;

            destination = (T)formatter.Deserialize(ms);
        }

        return destination;
    }
</code>```

For some reason the code errors out when the Deserialize function is called. The exception that it throws is that the assembly that the code is in cannot be found.

Unable to find assembly 'AssemblyBeingUsed, Version = 1.0.0.0, Culture=neutral, PublicKeyToken=null'

This is slightly confusing me as the assembly is already being accessed and its saying that it cannot be found. The code that formats the error message is part of the same assembly!

Here is the stack trace for the exception.

at System.Runtime.Serialization.Formatters.Binary.BinaryAssemblyInfo.GetAssembly()
     at System.Runtime.Serialization.Formatters.Binary.ObjectReader.GetType(BinaryAssemblyInfo assemblyInfo, String name)
     at System.Runtime.Serialization.Formatters.Binary.ObjectMap..ctor(String objectName, String[] memberNames, BinaryTypeEnum[] binaryTypeEnumA, Object[] typeInformationA, Int32[] memberAssemIds, ObjectReader objectReader, Int32 objectId, BinaryAssemblyInfo assemblyInfo, SizedArray assemIdToAssemblyTable)
     at System.Runtime.Serialization.Formatters.Binary.__BinaryParser.ReadObjectWithMapTyped(BinaryObjectWithMapTyped record)
     at System.Runtime.Serialization.Formatters.Binary.__BinaryParser.ReadObjectWithMapTyped(BinaryHeaderEnum binaryHeaderEnum)
     at System.Runtime.Serialization.Formatters.Binary.__BinaryParser.Run()
     at System.Runtime.Serialization.Formatters.Binary.ObjectReader.Deserialize(HeaderHandler handler, __BinaryParser serParser, Boolean fCheck, Boolean isCrossAppDomain, IMethodCallMessage methodCallMessage)
     at System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Deserialize(Stream serializationStream, HeaderHandler handler, Boolean fCheck, Boolean isCrossAppDomain, IMethodCallMessage methodCallMessage)

Edit: More useful information.

This function is never called directly from vb6. As it uses generics I'm pretty sure that this would be impossible anyway. This function is called from a form which is loaded from the vb6 application. When this form is used from a c# application there is no problem even though it is doing the exact same thing.

The Visual Studio project uses the "Register for COM interop" option and the assembly is loaded into the vb6 project as a reference.

Edit: Output from fuslogvw.exe

The output from fuslogvw.exe shows 5 entries associated with the assembly I'm interested in (BarcodeAndOperatorDatabase). As it is quite long when they are combined I have uploaded all the output to
this file.

To be honest I'm not sure what I'm looking at. There are 3 operations that I think correspond to when the assembly binds occur:

15:29:06: VB6 application started, operation was successful.

15:29:14 (2 entries): Form from assembly loaded (I think), operation failed. This is sort of confusing as the form loads correctly and can be interacted with.

15:29:50 (2 entries): Button click that fails when the CloneObject method is called, operation failed.

答:
TLDR Version:

The system can not locate the assembly.  The solution is to add a handler for AppDomain.CurrentDomain.AssemblyResolve event and return a reference to the needed assembly.

Long Version:

The stack trace finishes with System.Runtime.Serialization.Formatters.Binary.BinaryAssemblyInfo.GetAssembly().  If you follow the method calls in the source code a bit further down the chain, you will see that this following code is called.

```<code>    internal static Assembly LoadAssemblyFromString(String assemblyName) {
        //
        // Try using the stringized assembly name to load from the fusion cache.
        //
        BCLDebug.Trace("SER", "[LoadAssemblyFromString]Looking for assembly: ", assemblyName);
        Assembly found = Assembly.Load(assemblyName);
        return found;
    }
</code>```

The fusion log of this call is:

```<code>*** Assembly Binder Log Entry  (14/06/2017 @ 15:29:50) ***

The operation failed.
Bind result: hr = 0x80070002. The system cannot find the file specified.

Assembly manager loaded from:  C:\Windows\Microsoft.NET\Framework\v4.0.30319\clr.dll
Running under executable  C:\Program Files (x86)\Microsoft Visual Studio\VB98\vb6.exe
--- A detailed error log follows.

=== Pre-bind state information ===
LOG: DisplayName = BarcodeAndOperatorDatabase, Version=1.0.4.0, Culture=neutral, PublicKeyToken=null
 (Fully-specified)
LOG: Appbase = file:///C:/Program Files (x86)/Microsoft Visual Studio/VB98/
LOG: Initial PrivatePath = NULL
LOG: Dynamic Base = NULL
LOG: Cache Base = NULL
LOG: AppName = vb6.exe
Calling assembly : (Unknown).
===
LOG: This bind starts in default load context.
LOG: No application configuration file found.
LOG: Using host configuration file:
LOG: Using machine configuration file from C:\Windows\Microsoft.NET\Framework\v4.0.30319\config\machine.config.
LOG: Policy not being applied to reference at this time (private, custom, partial, or location-based assembly bind).
LOG: The same bind was seen before, and was failed with hr = 0x80070002.
ERR: Unrecoverable error occurred during pre-download check (hr = 0x80070002).
</code>```

The problem is that the system is probing the directory listed under 'Appbase` (C:\Program Files (x86)\Microsoft Visual Studio\VB98) and since required assembly is not located under that directory, it is not found.

Intitially when COM loads the CLR and the CLR loads the assembly, it is  based on the path stored in the registry.  This can be seen from this log entry.

```<code>=== Pre-bind state information ===
LOG: Where-ref bind. Location = D:/Development/Library/C Sharp/BarcodeAndOperatorDatabase/BarcodeAndOperatorDatabase/bin/x86/ComInterop/BarcodeAndOperatorDatabase.dll
LOG: Appbase = file:///C:/Program Files (x86)/Microsoft Visual Studio/VB98/
LOG: Initial PrivatePath = NULL
LOG: Dynamic Base = NULL
LOG: Cache Base = NULL
LOG: AppName = vb6.exe
Calling assembly : (Unknown).
===
LOG: This bind starts in LoadFrom load context.
WRN: Native image will not be probed in LoadFrom context. Native image will only be probed in default load context, like with Assembly.Load().
LOG: No application configuration file found.
LOG: Using host configuration file:
LOG: Using machine configuration file from C:\Windows\Microsoft.NET\Framework\v4.0.30319\config\machine.config.
LOG: Attempting download of new URL file:///D:/Development/Library/C Sharp/BarcodeAndOperatorDatabase/BarcodeAndOperatorDatabase/bin/x86/ComInterop/BarcodeAndOperatorDatabase.dll.
LOG: Assembly download was successful. Attempting setup of file: D:\Development\Library\C Sharp\BarcodeAndOperatorDatabase\BarcodeAndOperatorDatabase\bin\x86\ComInterop\BarcodeAndOperatorDatabase.dll
LOG: Entering run-from-source setup phase.
LOG: Assembly Name is: BarcodeAndOperatorDatabase, Version=1.0.4.0, Culture=neutral, PublicKeyToken=null
LOG: Re-apply policy for where-ref bind.
LOG: Where-ref bind Codebase does not match what is found in default context. Keep the result in LoadFrom context.
LOG: Binding succeeds. Returns assembly from D:\Development\Library\C Sharp\BarcodeAndOperatorDatabase\BarcodeAndOperatorDatabase\bin\x86\ComInterop\BarcodeAndOperatorDatabase.dll.
LOG: Assembly is loaded in LoadFrom load context.
</code>```

Initially the assembly exists only in the LoadFrom load context and can not be found when probing the default load context.  It is therefore necessary to provide a means to pass the LoadFrom assembly while probing the default load context.  This can be done by handling the AppDomain.AssemblyResolve Event.

The following excerpt from: Best Practices for Assembly Loading provides a description of the various contexts.

Within an application domain, assemblies can be loaded into one of
  three contexts, or they can be loaded without context:

The default load context contains assemblies found by probing the
  global assembly cache, the host assembly store if the runtime is
  hosted (for example, in SQL Server), and the ApplicationBase and
  PrivateBinPath of the application domain. Most overloads of the Load
  method load assemblies into this context.

The load-from context contains assemblies that are loaded from
  locations that are not searched by the loader. For example, add-ins
  might be installed in a directory that is not under the application
  path. System.Reflection.Assembly.LoadFrom,
  System.AppDomain.CreateInstanceFrom, and
  System.AppDomain.ExecuteAssembly are examples of methods that load by
  path.

The reflection-only context contains assemblies loaded with the
  ReflectionOnlyLoad and ReflectionOnlyLoadFrom methods. Code in this
  context cannot be executed, so it is not discussed here. For more
  information, see How to: Load Assemblies into the Reflection-Only
  Context.

ContentLicense: CC BY-SA 3.0

Body:
I have to update some old applications (vb6) and I have been using COM interop to write the new code in c# (Visual Studio 2010). Its mostly worked OK but I have come across a problem and I am not sure what is causing it.

I use the following method to perform a deep copy of an object

    public static T CloneObject<T>(T source)
    {
        T destination = default(T);

        if (!typeof(T).IsSerializable)
        {
            throw new ArgumentException("The type must be serialisable.", "source");
        }

        if (Object.ReferenceEquals(source, null))
        {
            return default(T);
        }

        using (Stream ms = new MemoryStream())
        {
            BinaryFormatter formatter = new BinaryFormatter();
            formatter.Serialize(ms, source);
            ms.Position = 0;

            destination = (T)formatter.Deserialize(ms);
        }

        return destination;
    }

For some reason the code errors out when the Deserialize function is called. The exception that it throws is that the assembly that the code is in cannot be found.

Unable to find assembly 'AssemblyBeingUsed, Version = 1.0.0.0, Culture=neutral, PublicKeyToken=null'

This is slightly confusing me as the assembly is already being accessed and its saying that it cannot be found. The code that formats the error message is part of the same assembly!

Here is the stack trace for the exception.

at System.Runtime.Serialization.Formatters.Binary.BinaryAssemblyInfo.GetAssembly()
     at System.Runtime.Serialization.Formatters.Binary.ObjectReader.GetType(BinaryAssemblyInfo assemblyInfo, String name)
     at System.Runtime.Serialization.Formatters.Binary.ObjectMap..ctor(String objectName, String[] memberNames, BinaryTypeEnum[] binaryTypeEnumA, Object[] typeInformationA, Int32[] memberAssemIds, ObjectReader objectReader, Int32 objectId, BinaryAssemblyInfo assemblyInfo, SizedArray assemIdToAssemblyTable)
     at System.Runtime.Serialization.Formatters.Binary.__BinaryParser.ReadObjectWithMapTyped(BinaryObjectWithMapTyped record)
     at System.Runtime.Serialization.Formatters.Binary.__BinaryParser.ReadObjectWithMapTyped(BinaryHeaderEnum binaryHeaderEnum)
     at System.Runtime.Serialization.Formatters.Binary.__BinaryParser.Run()
     at System.Runtime.Serialization.Formatters.Binary.ObjectReader.Deserialize(HeaderHandler handler, __BinaryParser serParser, Boolean fCheck, Boolean isCrossAppDomain, IMethodCallMessage methodCallMessage)
     at System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Deserialize(Stream serializationStream, HeaderHandler handler, Boolean fCheck, Boolean isCrossAppDomain, IMethodCallMessage methodCallMessage)

Edit: More useful information.

This function is never called directly from vb6. As it uses generics I'm pretty sure that this would be impossible anyway. This function is called from a form which is loaded from the vb6 application. When this form is used from a c# application there is no problem even though it is doing the exact same thing.

The Visual Studio project uses the "Register for COM interop" option and the assembly is loaded into the vb6 project as a reference.

Edit: Output from fuslogvw.exe

The output from fuslogvw.exe shows 5 entries associated with the assembly I'm interested in (BarcodeAndOperatorDatabase). As it is quite long when they are combined I have uploaded all the output to
this file.

To be honest I'm not sure what I'm looking at. There are 3 operations that I think correspond to when the assembly binds occur:

15:29:06: VB6 application started, operation was successful.

15:29:14 (2 entries): Form from assembly loaded (I think), operation failed. This is sort of confusing as the form loads correctly and can be interacted with.

15:29:50 (2 entries): Button click that fails when the CloneObject method is called, operation failed.

Body:
TLDR Version:

The system can not locate the assembly.  The solution is to add a handler for AppDomain.CurrentDomain.AssemblyResolve event and return a reference to the needed assembly.

Long Version:

The stack trace finishes with System.Runtime.Serialization.Formatters.Binary.BinaryAssemblyInfo.GetAssembly().  If you follow the method calls in the source code a bit further down the chain, you will see that this following code is called.

    internal static Assembly LoadAssemblyFromString(String assemblyName) {
        //
        // Try using the stringized assembly name to load from the fusion cache.
        //
        BCLDebug.Trace("SER", "[LoadAssemblyFromString]Looking for assembly: ", assemblyName);
        Assembly found = Assembly.Load(assemblyName);
        return found;
    }

The fusion log of this call is:

*** Assembly Binder Log Entry  (14/06/2017 @ 15:29:50) ***

The operation failed.
Bind result: hr = 0x80070002. The system cannot find the file specified.

Assembly manager loaded from:  C:\Windows\Microsoft.NET\Framework\v4.0.30319\clr.dll
Running under executable  C:\Program Files (x86)\Microsoft Visual Studio\VB98\vb6.exe
--- A detailed error log follows.

=== Pre-bind state information ===
LOG: DisplayName = BarcodeAndOperatorDatabase, Version=1.0.4.0, Culture=neutral, PublicKeyToken=null
 (Fully-specified)
LOG: Appbase = file:///C:/Program Files (x86)/Microsoft Visual Studio/VB98/
LOG: Initial PrivatePath = NULL
LOG: Dynamic Base = NULL
LOG: Cache Base = NULL
LOG: AppName = vb6.exe
Calling assembly : (Unknown).
===
LOG: This bind starts in default load context.
LOG: No application configuration file found.
LOG: Using host configuration file:
LOG: Using machine configuration file from C:\Windows\Microsoft.NET\Framework\v4.0.30319\config\machine.config.
LOG: Policy not being applied to reference at this time (private, custom, partial, or location-based assembly bind).
LOG: The same bind was seen before, and was failed with hr = 0x80070002.
ERR: Unrecoverable error occurred during pre-download check (hr = 0x80070002).

The problem is that the system is probing the directory listed under 'Appbase` (C:\Program Files (x86)\Microsoft Visual Studio\VB98) and since required assembly is not located under that directory, it is not found.

Intitially when COM loads the CLR and the CLR loads the assembly, it is  based on the path stored in the registry.  This can be seen from this log entry.

=== Pre-bind state information ===
LOG: Where-ref bind. Location = D:/Development/Library/C Sharp/BarcodeAndOperatorDatabase/BarcodeAndOperatorDatabase/bin/x86/ComInterop/BarcodeAndOperatorDatabase.dll
LOG: Appbase = file:///C:/Program Files (x86)/Microsoft Visual Studio/VB98/
LOG: Initial PrivatePath = NULL
LOG: Dynamic Base = NULL
LOG: Cache Base = NULL
LOG: AppName = vb6.exe
Calling assembly : (Unknown).
===
LOG: This bind starts in LoadFrom load context.
WRN: Native image will not be probed in LoadFrom context. Native image will only be probed in default load context, like with Assembly.Load().
LOG: No application configuration file found.
LOG: Using host configuration file:
LOG: Using machine configuration file from C:\Windows\Microsoft.NET\Framework\v4.0.30319\config\machine.config.
LOG: Attempting download of new URL file:///D:/Development/Library/C Sharp/BarcodeAndOperatorDatabase/BarcodeAndOperatorDatabase/bin/x86/ComInterop/BarcodeAndOperatorDatabase.dll.
LOG: Assembly download was successful. Attempting setup of file: D:\Development\Library\C Sharp\BarcodeAndOperatorDatabase\BarcodeAndOperatorDatabase\bin\x86\ComInterop\BarcodeAndOperatorDatabase.dll
LOG: Entering run-from-source setup phase.
LOG: Assembly Name is: BarcodeAndOperatorDatabase, Version=1.0.4.0, Culture=neutral, PublicKeyToken=null
LOG: Re-apply policy for where-ref bind.
LOG: Where-ref bind Codebase does not match what is found in default context. Keep the result in LoadFrom context.
LOG: Binding succeeds. Returns assembly from D:\Development\Library\C Sharp\BarcodeAndOperatorDatabase\BarcodeAndOperatorDatabase\bin\x86\ComInterop\BarcodeAndOperatorDatabase.dll.
LOG: Assembly is loaded in LoadFrom load context.

Initially the assembly exists only in the LoadFrom load context and can not be found when probing the default load context.  It is therefore necessary to provide a means to pass the LoadFrom assembly while probing the default load context.  This can be done by handling the AppDomain.AssemblyResolve Event.

The following excerpt from: Best Practices for Assembly Loading provides a description of the various contexts.

Within an application domain, assemblies can be loaded into one of
  three contexts, or they can be loaded without context:

The default load context contains assemblies found by probing the
  global assembly cache, the host assembly store if the runtime is
  hosted (for example, in SQL Server), and the ApplicationBase and
  PrivateBinPath of the application domain. Most overloads of the Load
  method load assemblies into this context.

The load-from context contains assemblies that are loaded from
  locations that are not searched by the loader. For example, add-ins
  might be installed in a directory that is not under the application
  path. System.Reflection.Assembly.LoadFrom,
  System.AppDomain.CreateInstanceFrom, and
  System.AppDomain.ExecuteAssembly are examples of methods that load by
  path.

The reflection-only context contains assemblies loaded with the
  ReflectionOnlyLoad and ReflectionOnlyLoadFrom methods. Code in this
  context cannot be executed, so it is not discussed here. For more
  information, see How to: Load Assemblies into the Reflection-Only
  Context.


问:
How to add an index to such sql query?
Please tell me how to add an index to this sql query?

SELECT *
FROM table
WHERE (cities IS NULL) AND (position_id = '2') AND (is_pub = '1')
ORDER BY ordering asc
LIMIT 1

Field types:

cities = text

position_id = int(11)

is_pub = tinyint(1)

I try so:
ALTER TABLE table ADD FULLTEXT ( 'cities', 'position_id', 'is_pub' );

But I get an error: The used table type doesn't support FULLTEXT indexes

答:
First, rewrite the query so you are not mixing types.  That is, get rid of the single quotes:

```<code>SELECT *
FROM table
WHERE (cities IS NULL) AND (position_id = 2) AND (is_pub = 1)
ORDER BY ordering asc
LIMIT 1;
</code>```

Then, the best query for this is on table(position_id, is_pub, cities, ordering):

```<code>create index idx_table_4 on table(position_id, is_pub, cities(32), ordering);
</code>```

The first three columns can be in any order in the index, so long as they are the first three.

You should change cities to a varchar() type.  Is there is reason you want to use a text for this?

Title: How to add an index to such sql query?

Body:
First, rewrite the query so you are not mixing types.  That is, get rid of the single quotes:

SELECT *
FROM table
WHERE (cities IS NULL) AND (position_id = 2) AND (is_pub = 1)
ORDER BY ordering asc
LIMIT 1;

Then, the best query for this is on table(position_id, is_pub, cities, ordering):

create index idx_table_4 on table(position_id, is_pub, cities(32), ordering);

The first three columns can be in any order in the index, so long as they are the first three.

You should change cities to a varchar() type.  Is there is reason you want to use a text for this?


问:
How to properly start nginx in Docker
I want nginx in a Docker container to host a simple static hello world html website. I want to simply start it with "docker run imagename". In order to do that I added the run parameters to the Dockerfile. The reason I want to do that is that I would like to host the application on Cloud Foundry in a next step. Unfortunately I get the following error when doing it like this.

Dockerfile

```<code>FROM nginx:alpine
COPY . /usr/share/nginx/html
EXPOSE 5000
CMD ["nginx -d -p 5000:5000"]
</code>```

Error

```<code>Error starting userland proxy: Bind for 0.0.0.0:5000: unexpected error Permission denied.
</code>```

答:
From ::
https://docs.docker.com/engine/reference/builder/#expose

EXPOSE does not make the ports of the container accessible to the host. To do that, you must use either the -p flag to publish a range of ports or the -P flag to publish all of the exposed ports. You can expose one port number and publish it externally under another number

CMD ["nginx -d -p 5000:5000"]
You add your dockerfile
FROM nginx:alpine
its already starts nginx.
after you build from your dockerfile

you should use this on

```<code>docker run -d -p 5000:5000 <your_image>
</code>```

Edit:
If you want to use docker port 80 -> machine port 5000

```<code>docker run -d -p 5000:80 <your_image>
</code>```

Title: How to properly start nginx in Docker

Body:
I want nginx in a Docker container to host a simple static hello world html website. I want to simply start it with "docker run imagename". In order to do that I added the run parameters to the Dockerfile. The reason I want to do that is that I would like to host the application on Cloud Foundry in a next step. Unfortunately I get the following error when doing it like this.

Dockerfile

FROM nginx:alpine
COPY . /usr/share/nginx/html
EXPOSE 5000
CMD ["nginx -d -p 5000:5000"]

Error

Error starting userland proxy: Bind for 0.0.0.0:5000: unexpected error Permission denied.

Body:
From ::
https://docs.docker.com/engine/reference/builder/#expose

EXPOSE does not make the ports of the container accessible to the host. To do that, you must use either the -p flag to publish a range of ports or the -P flag to publish all of the exposed ports. You can expose one port number and publish it externally under another number

CMD ["nginx -d -p 5000:5000"]
You add your dockerfile
FROM nginx:alpine
its already starts nginx.
after you build from your dockerfile

you should use this on

docker run -d -p 5000:5000 <your_image>

Edit:
If you want to use docker port 80 -> machine port 5000

docker run -d -p 5000:80 <your_image>


问:
AngularJS ng-show not working with $timeout?
I want to selected tab and showing 2 buttons.

so this is my aspx code :

```<code> <button id="UxMoveAllRight" style="width: 40px; height: 25px; margin-top: 20px;" ng-show="showMoveallButtons()">
                                <i class="pi-icon pi-icon-angle-double-right"></i>
                            </button>
                            <button id="UxMoveAllLeft" style="width: 40px; height: 25px; margin-bottom: 20px;" ng-show="showMoveallButtons()">
                                <i class="pi-icon pi-icon-angle-double-left"></i>
                            </button>
</code>```

and this is my ng-show function code (in controller.js):

```<code>$scope.showMoveallButtons = function () {
                    var show = false;
                    $timeout(function () {
                        var activetab = $find("Add").get_selectedTab().get_name();
                        if (activetab == "AddBulk") { show = true }
                        else { show = false };
                    });
                    return show;
                };
</code>```

but always return false.
I want to, if selected tab equals AddBulk , showing 2 button else not showing.

I guess, always return false reason : timeout ?

Do you any idea about how can I fix ?

答:
Use $scope.show in your timeOut() and affect her in your directive ng-show.

JS

```<code>$scope.showMoveallButtons = function () {
                    $timeout(function () {
                        var activetab = $find("Add").get_selectedTab().get_name();
                        if (activetab == "AddBulk") { $scope.show= true }
                        else { $scope.show= false };
                    },/*Your delay here*/);
                };
</code>```

HTML

```<code><button id="UxMoveAllRight" style="width: 40px; height: 25px; margin-top: 20px;" ng-show="show">
</code>```

Body:
I want to selected tab and showing 2 buttons.

so this is my aspx code :

 <button id="UxMoveAllRight" style="width: 40px; height: 25px; margin-top: 20px;" ng-show="showMoveallButtons()">

                            </button>
                            <button id="UxMoveAllLeft" style="width: 40px; height: 25px; margin-bottom: 20px;" ng-show="showMoveallButtons()">

                            </button>

and this is my ng-show function code (in controller.js):

$scope.showMoveallButtons = function () {
                    var show = false;
                    $timeout(function () {
                        var activetab = $find("Add").get_selectedTab().get_name();
                        if (activetab == "AddBulk") { show = true }
                        else { show = false };
                    });
                    return show;
                };

but always return false.
I want to, if selected tab equals AddBulk , showing 2 button else not showing.

I guess, always return false reason : timeout ?

Do you any idea about how can I fix ?

Body:
Use $scope.show in your timeOut() and affect her in your directive ng-show.

JS

$scope.showMoveallButtons = function () {
                    $timeout(function () {
                        var activetab = $find("Add").get_selectedTab().get_name();
                        if (activetab == "AddBulk") { $scope.show= true }
                        else { $scope.show= false };
                    },/*Your delay here*/);
                };

HTML

<button id="UxMoveAllRight" style="width: 40px; height: 25px; margin-top: 20px;" ng-show="show">


问:
Unable to run appium tests on iOS real device using windows 10 machine
I am trying to run my appium tests on iPhone 5S which has plugged into Windows 10 computer. But It is not working. Can someone help me how to run the appium tests on iOS real device by using a Windows PC? Below are the desired capabilities I have used.</p>

```<code>    public class WebTest {
      AppiumDriver driver;
      DesiredCapabilities capabilities = new DesiredCapabilities();

     @BeforeClass()
     public void init() throws MalformedURLException {
       capabilities.setCapability("platformName", "iOS");
       capabilities.setCapability("deviceName", "iPhone 5s");
       capabilities.setCapability("browser", "safari");
        driver = new IOSDriver(new URL("http://127.0.0.1:4723/wd/hub"),
            capabilities);
        driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
}

 @Test
  public void googleTest() {
    driver.get("http://www.google.com");
  }
}
</code>```

答:
As far as I know, it is impossible to automate iOS device on Windows because XCode is unavailable for Windows.
You could try to run Virtual Machine with MacOS and run automated tests from there.
There's this site which allows you to automate remote device from Windows machine (paid, probably).</p>

Body:
I am trying to run my appium tests on iPhone 5S which has plugged into Windows 10 computer. But It is not working. Can someone help me how to run the appium tests on iOS real device by using a Windows PC? Below are the desired capabilities I have used.

    public class WebTest {
      AppiumDriver driver;
      DesiredCapabilities capabilities = new DesiredCapabilities();

     @BeforeClass()
     public void init() throws MalformedURLException {
       capabilities.setCapability("platformName", "iOS");
       capabilities.setCapability("deviceName", "iPhone 5s");
       capabilities.setCapability("browser", "safari");
        driver = new IOSDriver(new URL("http://127.0.0.1:4723/wd/hub"),
            capabilities);
        driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
}

 @Test
  public void googleTest() {
    driver.get("http://www.google.com");
  }
}


问:
Why , in pase tree , ANTLR keep mismatching input?
I am new with ANTLR4 and I am trying to visualize the Parse Tree  of a text input in a simple form :

```<code>grammar Expr;
contract: (I WS SEND WS quantity WS asset WS TO WS beneficiary WS ON WS send_date WS)*;
asset: '$'| 'TND' | 'USD';
quantity:Q;
beneficiary: B;
send_date : day SLASH month SLASH year;
day: D ;
month: M ;
year: Y ;
B : LETTERUP (LETTERLOW+)+ LETTERLOW*;
Q : DIGITO DIGITZ*|DIGITO DIGITZ* POINT DIGITZ*;
D : DIGIT0 DIGITO|(DIGIT1|DIGIT2)DIGITZ|DIGIT3(DIGIT0|DIGIT1);
M : DIGIT0 DIGITO| DIGIT1(DIGIT0|DIGIT1|DIGIT2);
Y : DIGIT2 DIGIT0((DIGIT1(DIGIT7|DIGIT8|DIGIT9))|(DIGIT2 DIGITZ));
I: 'I';
SEND: 'send';
TO:'to' ;
ON: 'on';
LETTER : [a-zA-Z];
LETTERUP : [A-Z];
LETTERLOW : [a-z];
DIGITZ : [0-9];
DIGITO : [1-9];
DIGIT0 : [0];
DIGIT1 : [1];
DIGIT2 : [2];
DIGIT3 : [3];
DIGIT4 : [4];
DIGIT5 : [5];
DIGIT6 : [6];
DIGIT7 : [7];
DIGIT8 : [8];
DIGIT9 : [9];
SLASH:'/';
POINT:'.'|',';
WS : (' ' | '\t' |'\n' |'\r' )+ ;
</code>```

But it keeps mismatching the send_date as you can see here:

I know it is a seriously complex numerical grammar I did just want some control the 01<= day <= 31 , 01<= month <= 12 and 2017<= year <= 2029 that's all
is there any help? and thanks

答:
That's a seriously complex numerical grammar.  Perhaps you could simplify:

```<code>day: NUMBER ;
month: NUMBER ;
year: NUMBER ;

NUMBER : DIGITZ+ ;
DIGITZ : [0-9];
</code>```

You could enforce semantics like limiting year to [2017...2020] or whatever in your code.  Just an idea.  Simplifying often helps and then you can enhance it from there, knowing if you make a mistake you can always revert to something that will at least work.

EDIT:

The reason your grammar doesn't work is because the month is being lexed as a day:

```<code>[@0,0:0='I',<'I'>,1:0]
[@1,1:1=' ',<WS>,1:1]
[@2,2:5='send',<'send'>,1:2]
[@3,6:6=' ',<WS>,1:6]
[@4,7:9='300',<Q>,1:7]
[@5,10:10=' ',<WS>,1:10]
[@6,11:11='$',<'$'>,1:11]
[@7,12:12=' ',<WS>,1:12]
[@8,13:14='to',<'to'>,1:13]
[@9,15:15=' ',<WS>,1:15]
[@10,16:20='Ahmed',<B>,1:16]
[@11,21:21=' ',<WS>,1:21]
[@12,22:23='on',<'on'>,1:22]
[@13,24:24=' ',<WS>,1:24]
[@14,25:26='03',<D>,1:25]
[@15,27:27='/',<'/'>,1:27]
[@16,28:29='07',<D>,1:28]  <-- see, this is being lexed as a D (day)
[@17,30:30='/',<'/'>,1:30]
[@18,31:34='2017',<Q>,1:31] <-- and this is being lexed as a Q (quantity)
[@19,35:36='\r\n',<WS>,1:35]
[@20,37:36='<EOF>',<EOF>,2:0]
line 1:28 mismatched input '05' expecting M
line 1:31 mismatched input '2017' expecting Y
</code>```

Lexer rules are applied in the order in which they appear, and Day appears before Month.  Quantity appears before Year.  Hence the improper lexing.  This is a scenario, honestly, where I think you need to simplify and just accept numbers.  Then in your code, enforce the semantics (make sure year is in range, etc) in your code and provide a helpful error message to the user if values are not in range.  Your total effort spend will be less that way.

NEW VERSION

```<code>grammar Test2;
contract: (I SEND quantity asset TO beneficiary ON send_date)*;

asset: '$'| 'TND' | 'USD';
send_date : DATE ;
quantity: NUMBER;
beneficiary: B;

DATE : NUMBER SLASH NUMBER SLASH NUMBER ;
B : LETTERUP (LETTERLOW+)+ LETTERLOW*;
I: 'I';
SEND: 'send';
TO:'to' ;
ON: 'on';
LETTER : [a-zA-Z];
LETTERUP : [A-Z];
LETTERLOW : [a-z];
NUMBER: DIGIT+;
DIGIT : [0-9];
SLASH:'/';
POINT:'.'|',';
WS : [ \t\n\r]+ -> skip;
</code>```

Improvements:
1. Better handling of whitespace much more conventional.
2. Simplified number syntax.
3. It works

```<code>[@0,0:0='I',<'I'>,1:0]
[@1,2:5='send',<'send'>,1:2]
[@2,7:9='300',<NUMBER>,1:7]
[@3,11:11='$',<'$'>,1:11]
[@4,13:14='to',<'to'>,1:13]
[@5,16:20='Ahmed',<B>,1:16]
[@6,22:23='on',<'on'>,1:22]
[@7,25:34='03/07/2017',<DATE>,1:25]
[@8,37:36='<EOF>',<EOF>,2:0]
</code>```

Problem: I simplified away the ability to do decimal numbers for quantity.  You can add that back in as you wish.

Body:
I am new with ANTLR4 and I am trying to visualize the Parse Tree  of a text input in a simple form :

grammar Expr;
contract: (I WS SEND WS quantity WS asset WS TO WS beneficiary WS ON WS send_date WS)*;
asset: '$'| 'TND' | 'USD';
quantity:Q;
beneficiary: B;
send_date : day SLASH month SLASH year;
day: D ;
month: M ;
year: Y ;
B : LETTERUP (LETTERLOW+)+ LETTERLOW*;
Q : DIGITO DIGITZ*|DIGITO DIGITZ* POINT DIGITZ*;
D : DIGIT0 DIGITO|(DIGIT1|DIGIT2)DIGITZ|DIGIT3(DIGIT0|DIGIT1);
M : DIGIT0 DIGITO| DIGIT1(DIGIT0|DIGIT1|DIGIT2);
Y : DIGIT2 DIGIT0((DIGIT1(DIGIT7|DIGIT8|DIGIT9))|(DIGIT2 DIGITZ));
I: 'I';
SEND: 'send';
TO:'to' ;
ON: 'on';
LETTER : [a-zA-Z];
LETTERUP : [A-Z];
LETTERLOW : [a-z];
DIGITZ : [0-9];
DIGITO : [1-9];
DIGIT0 : [0];
DIGIT1 : [1];
DIGIT2 : [2];
DIGIT3 : [3];
DIGIT4 : [4];
DIGIT5 : [5];
DIGIT6 : [6];
DIGIT7 : [7];
DIGIT8 : [8];
DIGIT9 : [9];
SLASH:'/';
POINT:'.'|',';
WS : (' ' | '\t' |'\n' |'\r' )+ ;

But it keeps mismatching the send_date as you can see here:

I know it is a seriously complex numerical grammar I did just want some control the 01<= day <= 31 , 01<= month <= 12 and 2017<= year <= 2029 that's all
is there any help? and thanks

Body:
That's a seriously complex numerical grammar.  Perhaps you could simplify:

day: NUMBER ;
month: NUMBER ;
year: NUMBER ;

NUMBER : DIGITZ+ ;
DIGITZ : [0-9];

You could enforce semantics like limiting year to [2017...2020] or whatever in your code.  Just an idea.  Simplifying often helps and then you can enhance it from there, knowing if you make a mistake you can always revert to something that will at least work.

EDIT:

The reason your grammar doesn't work is because the month is being lexed as a day:

[@0,0:0='I',<'I'>,1:0]
[@1,1:1=' ',<WS>,1:1]
[@2,2:5='send',<'send'>,1:2]
[@3,6:6=' ',<WS>,1:6]
[@4,7:9='300',<Q>,1:7]
[@5,10:10=' ',<WS>,1:10]
[@6,11:11='$',<'$'>,1:11]
[@7,12:12=' ',<WS>,1:12]
[@8,13:14='to',<'to'>,1:13]
[@9,15:15=' ',<WS>,1:15]
[@10,16:20='Ahmed',<B>,1:16]
[@11,21:21=' ',<WS>,1:21]
[@12,22:23='on',<'on'>,1:22]
[@13,24:24=' ',<WS>,1:24]
[@14,25:26='03',<D>,1:25]
[@15,27:27='/',<'/'>,1:27]
[@16,28:29='07',<D>,1:28]  <-- see, this is being lexed as a D (day)
[@17,30:30='/',<'/'>,1:30]
[@18,31:34='2017',<Q>,1:31] <-- and this is being lexed as a Q (quantity)
[@19,35:36='\r\n',<WS>,1:35]
[@20,37:36='<EOF>',<EOF>,2:0]
line 1:28 mismatched input '05' expecting M
line 1:31 mismatched input '2017' expecting Y

Lexer rules are applied in the order in which they appear, and Day appears before Month.  Quantity appears before Year.  Hence the improper lexing.  This is a scenario, honestly, where I think you need to simplify and just accept numbers.  Then in your code, enforce the semantics (make sure year is in range, etc) in your code and provide a helpful error message to the user if values are not in range.  Your total effort spend will be less that way.

NEW VERSION

grammar Test2;
contract: (I SEND quantity asset TO beneficiary ON send_date)*;

asset: '$'| 'TND' | 'USD';
send_date : DATE ;
quantity: NUMBER;
beneficiary: B;

DATE : NUMBER SLASH NUMBER SLASH NUMBER ;
B : LETTERUP (LETTERLOW+)+ LETTERLOW*;
I: 'I';
SEND: 'send';
TO:'to' ;
ON: 'on';
LETTER : [a-zA-Z];
LETTERUP : [A-Z];
LETTERLOW : [a-z];
NUMBER: DIGIT+;
DIGIT : [0-9];
SLASH:'/';
POINT:'.'|',';
WS : [ \t\n\r]+ -> skip;

Improvements:
1. Better handling of whitespace much more conventional.
2. Simplified number syntax.
3. It works

[@0,0:0='I',<'I'>,1:0]
[@1,2:5='send',<'send'>,1:2]
[@2,7:9='300',<NUMBER>,1:7]
[@3,11:11='$',<'$'>,1:11]
[@4,13:14='to',<'to'>,1:13]
[@5,16:20='Ahmed',<B>,1:16]
[@6,22:23='on',<'on'>,1:22]
[@7,25:34='03/07/2017',<DATE>,1:25]
[@8,37:36='<EOF>',<EOF>,2:0]

Problem: I simplified away the ability to do decimal numbers for quantity.  You can add that back in as you wish.


问:
Iteratively reveal one html table row after the other upon clicking a button
I have a html table with a fixed number of rows, of which only the first one is visible from the beginning. Upon clicking a button, row 2 should be revealed. Upon clicking the same button again, row 3 should be revealed, and so on.

Importantly, the full table should be loaded at the beginning (each row contains a specific django formfield), so I do not want to generate additional html rows when clicking the button.
I found lots of stuff on toggling/showing table rows using jQuery, but what I want to do here is I want to show additional rows each time the button is clicked.
My idea was to first initiate and then increment a variable upon clicking in Javascript, and then show an additional row each time. I failed.

I am newbie to Javascript, any suggestions highly appreciated!

$(document).ready(function() {
  var counter = 1;
  var $rows = $("#fullTable tr");
  $("RevealRow").click(function() {
    counter++;
    $rows.eq(counter).show();
  });
});```
<pre class="snippet-code-html lang-html prettyprint-override"><code><script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table id="fullTable">
  <tr>
    <td>Row 1</td>
  </tr>
  <tr style="display:none;">
    <td>Row 2</td>
  </tr>
  <tr style="display:none;">
    <td>Row 3</td>
  </tr>
  <tr style="display:none;">
    <td>Row 4</td>
  </tr>
  <tr style="display:none;">
    <td>Row 5</td>
  </tr>
  <tr style="display:none;">
    <td>Row 6</td>
  </tr>
</table>

<button id="RevealRow">Show more rows</button></code>```

答:
Try this jQuery code</p>

```<code>$(document).ready(function () {
            $("#RevealRow").click(function () {
                $("#fullTable tr:visible").next().show();
            });
        });
</code>```

Body:
I have a html table with a fixed number of rows, of which only the first one is visible from the beginning. Upon clicking a button, row 2 should be revealed. Upon clicking the same button again, row 3 should be revealed, and so on.

Importantly, the full table should be loaded at the beginning (each row contains a specific django formfield), so I do not want to generate additional html rows when clicking the button.
I found lots of stuff on toggling/showing table rows using jQuery, but what I want to do here is I want to show additional rows each time the button is clicked.
My idea was to first initiate and then increment a variable upon clicking in Javascript, and then show an additional row each time. I failed.

I am newbie to Javascript, any suggestions highly appreciated!

$(document).ready(function() {
  var counter = 1;
  var $rows = $("#fullTable tr");
  $("RevealRow").click(function() {
    counter++;
    $rows.eq(counter).show();
  });
});

    Row 1

    Row 2

    Row 3

    Row 4

    Row 5

    Row 6

<button id="RevealRow">Show more rows</button>

Body:
Try this jQuery code

$(document).ready(function () {
            $("#RevealRow").click(function () {
                $("#fullTable tr:visible").next().show();
            });
        });


问:
Rest API fields restrict for role
I'm designing some REST API and just wondering how to restrict frontend users access some of resource fields.

Lets say this is our user resource:

```<code>{
  "username" : "user",
  "email" : "email@example.com",
  "created_at" : "2011-06-13T21:56:36"
}
</code>```

It's obvious that email shouldn't be disclosed and returned to public audience. However in admin section I would like to receive this field.

Is there any kind of strategies for such problems?

My ideas:

Create separate endpoints for administration.

Auth mechanism for fields?

答:
Creating a proper authentication mechanism in a REST API is (i) not trivial, and (ii) already done in many many languages. Unless for learning purposes, I would suggest not to rewrite that.

Depending on your backend language of choice, you can choose a framework to do exactly that. For example, in Python, I would suggest Django with Django Rest Framework.

Title: Rest API fields restrict for role

Body:
I'm designing some REST API and just wondering how to restrict frontend users access some of resource fields.

Lets say this is our user resource:

{
  "username" : "user",
  "email" : "email@example.com",
  "created_at" : "2011-06-13T21:56:36"
}

It's obvious that email shouldn't be disclosed and returned to public audience. However in admin section I would like to receive this field.

Is there any kind of strategies for such problems?

My ideas:

Create separate endpoints for administration.

Auth mechanism for fields?


问:
Passing context of view on event in backbone.js
I have a context problem / design problem for my Backbone view.

Goal

The user selects a user from a list / user collection in a separate view.

The mentioned view passes an global event that the editUserView receives ("edit-contact").

The editUserView should receive this event and extract the (user) model.id attribute. By using this model.id I want to update the view with the corresponding object retrieved from the existing view model Tsms.Collection.Users.

Problem

The context passed to the updateView function is wrong, and thus I do not have access to the parent views .render() function. The debugger states "render() is not a function".

Since the context is not that of the parent view I am also unable to set the this.current variable.

How would I go about solving this problem?

View code

```<code>Tsms.Views.editUserView = Backbone.View.extend({
    model: Tsms.Collections.Users,
    initialize: function(options) {
        Tsms.require_template('edituser')
        this.template = _.template($('#template_edituser').html());
        this.current = -1;

        Tsms.vent.on('edit-contact', this.updateView)
    },
    updateView: function(model) {
        this.current = model.id;
        this.render();
    },
    render: function() {
        this.$el.html(this.template(this.model.get(this.current).attributes));
        return this;
    }
});
</code>```

答:
While mu is too short is right, you should use Backbone's listenTo to avoid memory leaks (zombie views).

```<code>this.listenTo(Tsms.vent, 'edit-contact', this.updateView);
</code>```

The context is automatically set to this, the calling view.

When remove is called on the view, stopListening is called and any references kept for events are removed.

Another reason to avoid on is that it should be the view that is responsible for the events it wants to handle, the event bus shouldn't have to know.

Body:
I have a context problem / design problem for my Backbone view.

Goal

The user selects a user from a list / user collection in a separate view.

The mentioned view passes an global event that the editUserView receives ("edit-contact").

The editUserView should receive this event and extract the (user) model.id attribute. By using this model.id I want to update the view with the corresponding object retrieved from the existing view model Tsms.Collection.Users.

Problem

The context passed to the updateView function is wrong, and thus I do not have access to the parent views .render() function. The debugger states "render() is not a function".

Since the context is not that of the parent view I am also unable to set the this.current variable.

How would I go about solving this problem?

View code

Tsms.Views.editUserView = Backbone.View.extend({
    model: Tsms.Collections.Users,
    initialize: function(options) {
        Tsms.require_template('edituser')
        this.template = _.template($('#template_edituser').html());
        this.current = -1;

        Tsms.vent.on('edit-contact', this.updateView)
    },
    updateView: function(model) {
        this.current = model.id;
        this.render();
    },
    render: function() {
        this.$el.html(this.template(this.model.get(this.current).attributes));
        return this;
    }
});

Body:
While mu is too short is right, you should use Backbone's listenTo to avoid memory leaks (zombie views).

this.listenTo(Tsms.vent, 'edit-contact', this.updateView);

The context is automatically set to this, the calling view.

When remove is called on the view, stopListening is called and any references kept for events are removed.

Another reason to avoid on is that it should be the view that is responsible for the events it wants to handle, the event bus shouldn't have to know.


问:
How do I deserialize a collection of references to a struct equivalent?
NOTE: This question changed a little as I learned more about the problem, so please read it in its entirety. I've decided to leave it in its original form as it better describes how the problem was discovered and ultimately resolved.

Way back in the darkest depths of our project's history when we didn't really understand C# or the CLR as well as we might've, we created a type, let's call it MyType. We created this type as a class, a reference type.

However, it became apparent that MyType should be a struct, a value type so we made some changes to make it so and all was well until one day, we tried to deserialize some data that contained a collection of MyType values. Well, not really, for when it was a reference type, that collection was a collection of references. Now when it deserializes, the collection deserializes fine, using the default constructor of MyType, then later when the actual references deserialize, they are orphaned, leaving us with a collection of empty values.

So, we thought, "let's map the type to a reference type, MyTypeRef on load so that the references properly resolve, then convert back to our real type for use during execution time and reserialization". So we did (using our own binder), but alas, it didn't work because now we get an error that tells us MyTypeRef[] can't be converted to MyType[] even if we have an implicit conversion between MyTypeRef and MyType.

So, we're stuck. How do we get a collection serialized as a collection of reference type MyType to deserialize as a collection of value type MyType?

Update

Some investigation (see comments and code below) has shown that it is the immutable nature of the new MyType and its used of ISerializable for serialization that has caused the real issue. I still don't see why that should be the case, but if I use private set accessors instead of ISerializable, the new MyType will load the old (note that the ISerializable interface is called if I use it but the collection only even contains default values).

Some code

```<code>// Use a List<T> in a class that also implements ISerializable and
// save an instance of that class with a BinaryFormatter (code omitted)

// Save with this one.
[Serializable]
public class MyType
{
    private string test;
    public string Test
    {
        get { return this.test; }
        set { this.test = value; }
    }

    public MyType()
    {
    }
}

// Load with this one.
[Serializable]
public class MyType : ISerializable
{
    private string test;
    public string Test
    {
        get { return this.test; }
        set { this.test = value; }
    }

    public MyType()
    {
    }

    public MyType(SerializationInfo info, StreamingContext context)
    {
        info.AddValue("test", this.test);
    }

    public void GetObjectData(SerializationInfo info, StreamingContext context)
    {
        this.test = info.GetString("test");
    }
}
</code>```

Note that when loading, the elements are all nulls. Remove ISerializable from the second definition and load and all works. Change class to struct on the load code and the same behaviour is visible. It is as though the collection will only deserialize successfully using the set accessors.

Update Two

So, I found the problem (see my answer below) but I doubt anyone would've known the answer from reading my question. I missed out an important detail that I didn't even realise was important at the time. My sincerest apologies to those who tried to help.

The collection that is loaded containing MyType is immediately copied to another collection during GetObjectData. The answer below explains why this turns out to be important. Here is some additional sample code to that given above that should provide a complete example:

```<code>public void GetObjectData(SerializationInfo info, StreamingContext context)
{
    this.myTypeCollection = new List<MyType>();
    var loadedCollection = (List<MyType>)info.GetValue(
        "myTypeCollection",
        typeof(List<MyType>));
    this.myTypeCollection.AddRange(loadedCollection);
}
</code>```

答:
I feel somewhat foolish now but I discovered the issue. I have updated the question with additional sample code.

Here is the basics of what the code was doing in the GetObjectData method:

Load the collection

Copy the collection into another collection

Here is the sequence that occurred at execution:

Collection loaded but elements are not

Copied null/default elements to another collection and discarded loaded collection variable

Elements of loaded collection are deserialized

Note that it is only after point 3 that the entire collection is deserialized but I have already done my copy, hence having nothing.

The fix was to use the OnDeserialized attribute to specify a method to call once the entire object was deserialized. Then, in GetObjectData I save away a reference to the collection that is loaded, but copy its contents in the OnDeserialized method once it is fully deserialized.

Side note

In fact, to keep the deserialization code all in GetObjectData, I saved away a delegate to perform the copy and I call that delegate later - that way it is clear in GetObjectData exactly what will happen to finish deserialization.

Code

```<code>public void GetObjectData(SerializationInfo info, StreamingContext context)
{
    var loadedCollection = (List<MyType>)info.GetValue(
        "myTypeCollection",
        typeof(List<MyType>));

    this.myTypeCollectionLoader = () =>
    {
        this.myTypeCollection.AddRange(loadedCollection);
    };
}

[OnDeserialized]
private void OnDeserialized(StreamingContext context)
{
    this.myTypeCollectionLoader();
    this.myTypeCollectionLoader = null;
}
</code>```

ContentLicense: CC BY-SA 2.5

Body:
NOTE: This question changed a little as I learned more about the problem, so please read it in its entirety. I've decided to leave it in its original form as it better describes how the problem was discovered and ultimately resolved.

Way back in the darkest depths of our project's history when we didn't really understand C# or the CLR as well as we might've, we created a type, let's call it MyType. We created this type as a class, a reference type.

However, it became apparent that MyType should be a struct, a value type so we made some changes to make it so and all was well until one day, we tried to deserialize some data that contained a collection of MyType values. Well, not really, for when it was a reference type, that collection was a collection of references. Now when it deserializes, the collection deserializes fine, using the default constructor of MyType, then later when the actual references deserialize, they are orphaned, leaving us with a collection of empty values.

So, we thought, "let's map the type to a reference type, MyTypeRef on load so that the references properly resolve, then convert back to our real type for use during execution time and reserialization". So we did (using our own binder), but alas, it didn't work because now we get an error that tells us MyTypeRef[] can't be converted to MyType[] even if we have an implicit conversion between MyTypeRef and MyType.

So, we're stuck. How do we get a collection serialized as a collection of reference type MyType to deserialize as a collection of value type MyType?

Update

Some investigation (see comments and code below) has shown that it is the immutable nature of the new MyType and its used of ISerializable for serialization that has caused the real issue. I still don't see why that should be the case, but if I use private set accessors instead of ISerializable, the new MyType will load the old (note that the ISerializable interface is called if I use it but the collection only even contains default values).

Some code

// Use a List<T> in a class that also implements ISerializable and
// save an instance of that class with a BinaryFormatter (code omitted)

// Save with this one.
[Serializable]
public class MyType
{
    private string test;
    public string Test
    {
        get { return this.test; }
        set { this.test = value; }
    }

    public MyType()
    {
    }
}

// Load with this one.
[Serializable]
public class MyType : ISerializable
{
    private string test;
    public string Test
    {
        get { return this.test; }
        set { this.test = value; }
    }

    public MyType()
    {
    }

    public MyType(SerializationInfo info, StreamingContext context)
    {
        info.AddValue("test", this.test);
    }

    public void GetObjectData(SerializationInfo info, StreamingContext context)
    {
        this.test = info.GetString("test");
    }
}

Note that when loading, the elements are all nulls. Remove ISerializable from the second definition and load and all works. Change class to struct on the load code and the same behaviour is visible. It is as though the collection will only deserialize successfully using the set accessors.

Update Two

So, I found the problem (see my answer below) but I doubt anyone would've known the answer from reading my question. I missed out an important detail that I didn't even realise was important at the time. My sincerest apologies to those who tried to help.

The collection that is loaded containing MyType is immediately copied to another collection during GetObjectData. The answer below explains why this turns out to be important. Here is some additional sample code to that given above that should provide a complete example:

public void GetObjectData(SerializationInfo info, StreamingContext context)
{
    this.myTypeCollection = new List<MyType>();
    var loadedCollection = (List<MyType>)info.GetValue(
        "myTypeCollection",
        typeof(List<MyType>));
    this.myTypeCollection.AddRange(loadedCollection);
}

Body:
I feel somewhat foolish now but I discovered the issue. I have updated the question with additional sample code.

Here is the basics of what the code was doing in the GetObjectData method:

Load the collection

Copy the collection into another collection

Here is the sequence that occurred at execution:

Collection loaded but elements are not

Copied null/default elements to another collection and discarded loaded collection variable

Elements of loaded collection are deserialized

Note that it is only after point 3 that the entire collection is deserialized but I have already done my copy, hence having nothing.

The fix was to use the OnDeserialized attribute to specify a method to call once the entire object was deserialized. Then, in GetObjectData I save away a reference to the collection that is loaded, but copy its contents in the OnDeserialized method once it is fully deserialized.

Side note

In fact, to keep the deserialization code all in GetObjectData, I saved away a delegate to perform the copy and I call that delegate later - that way it is clear in GetObjectData exactly what will happen to finish deserialization.

Code

public void GetObjectData(SerializationInfo info, StreamingContext context)
{
    var loadedCollection = (List<MyType>)info.GetValue(
        "myTypeCollection",
        typeof(List<MyType>));

    this.myTypeCollectionLoader = () =>
    {
        this.myTypeCollection.AddRange(loadedCollection);
    };
}

[OnDeserialized]
private void OnDeserialized(StreamingContext context)
{
    this.myTypeCollectionLoader();
    this.myTypeCollectionLoader = null;
}


问:
How do you declare a global constant in Python?
I have some heavy calculations that I want to do when my program starts, and then I want to save the result (a big bumpy matrix) in memory so that I can use it again and again. My program contains multiple files and classes, and I would like to be able to access this variable from anywhere, and if possible define it as constant.

How do you define a global constant in Python?

答:
I do not think the marked as good answer solves the op question. The global keyword in Python is used to modify a global variable in a local context (as explained here). This means that if the op modifies SOME_CONSTANT within myfunc the change will affect also outside the function scope (globally).

Not using the global keyword at the begining of myfunc is closer to the sense of global constant than the one suggested. Despite there are no means to render a value constant or immutable in Python.

ContentLicense: CC BY-SA 4.0


问:
Filter list results with <select/> drop-down list value
I am trying to filter a 'Project Index' by tags using jQuery and CSS.

I am currently taking the .val() of the selected option in a <select> dropdown list and checking if it's equal to the inner .html() of a .tag. If they match it will make the project entry black, if else it will make it light gray.

My current code works when the project has one tag, but once there are multiple tags it breaks. My guess is that because although there is one .tag equal to the selected dropdown value, the other .tag are not,  therefore using the else condition?

What am I missing? Is there a better/more efficient way to do this?

HTML

```<code><main>
  <div class="index__container">
     <section class="index">
        <ul class="index__header">
            <li>Project</li>
            <li>Filter: <select id="index__filter">
                <option selected="selected" value='ALL'>All</option>
                <option value="Pedagogical Explorations">Pedagogical Explorations</option>
                <option value="Research Production">Research Production</option>
                <option value="Spatial Practice">Spatial Practice</option>
                <option value="Exhibition">Exhibition</option>
            </select></li>
            <li>Year</li>
        </ul>
        <a href="">
            <ul class="index__entry">
                <li>Multiscale Strategies to Reactivate Transhumance in Spain</li>
                <li>
                    <span class="tag">Spatial Practice</span>
                </li>
                <li>2017</li>
            </ul>
        </a>
        <a href="">
            <ul class="index__entry">
                <li>Architecture after Speculation</li>
                <li>
                    <span class="tag">Research Production</span>
                </li>
                <li>2017</li>
            </ul>
        </a>
        <a href="">
            <ul class="index__entry">
                <li>Polyester Merino Chair</li>
                <li>
                    <span class="tag">Spatial Practice</span>
                </li>
                <li>2017</li>
            </ul>
        </a>
        <a href="">
            <ul class="index__entry">
                <li>1500 caracteres</li>
                <li>
                    <span class="tag">Spatial Practice</span>
                    <span class="tag">Research Production</span>
                </li>
                <li>2017</li>
            </ul>
        </a>
        <a href="">
            <ul class="index__entry">
                <li>Europan 13: Die Arbeitersiedlung</li>
                <li>
                    <span class="tag">Spatial Practice</span>
                </li>
                <li>2015</li>
            </ul>
        </a>
        <a href="">
            <ul class="index__entry">
                <li>Asymmetric Meta-Mapping</li>
                <li>
                    <span class="tag">Pedagogical Explorations</span>
                </li>
                <li>2017</li>
             </ul>
        </a>
        <a href="">
            <ul class="index__entry">
                <li>Chicago Architecture Biennial</li>
                <li>
                    <span class="tag">Spatial Practice</span>
                    <span class="tag">Research Production</span>
                    <span class="tag">Exhibition</span></li>
                <li>2015</li>
            </ul>
        </a>
    </section>
</div>
</code>```

JS

```<code>  // Filter Project Index
  var $indexSelect = $('#index__filter');
  var $indexEntry = $('.index__entry');
  var $tag = $('.tag');

  $indexSelect.change(function(){
    var selectedValue = $(this).val();
    if(selectedValue == 'ALL'){
       $indexEntry.css('color', 'black');
     return;
    }

    $tag.each(function(i,option){
     if ($(this).html() == selectedValue) {
        $(this).closest('ul').css('color', 'black');
        console.log($(this).text());
      } else {
       $(this).closest('ul').css('color', 'lightgray');
      }
    });
  });
</code>```

答:
Because you're looping trough all the tags, and aply styling for each tag it will only show the styling for the last tag of each entry.

If you loop per entry, and than per tag in each entry you can break out of the loop once you have found a tag that matches the selected tag.

```<code>// loop trough each entry
$indexEntry.each(function(i,entry){
  // loop trough tag iwithin the entry
  $( this ).find( '.tag' ).each(function(i, tag){
    if ($(this).html() == selectedValue) {
        $(this).closest('ul').css('color', 'black');
        // exit this loop as soon as we've determined it should be black
        return false;
    } else {
       $(this).closest('ul').css('color', 'lightgray');
    }
  })
})
</code>```

$(function(){
// Filter Project Index
  var $indexSelect = $('#index__filter');
  var $indexEntry = $('.index__entry');
  var $tag = $('.tag');

  $indexSelect.change(function(){
    var selectedValue = $(this).val();
    if(selectedValue == 'ALL'){
       $indexEntry.css('color', 'black');
     return;
    }

    $indexEntry.each(function(i,entry){
      $( this ).find( '.tag' ).each(function(i, tag){
        if ($(this).html() == selectedValue) {
            $(this).closest('ul').css('color', 'black');
            return false;
            console.log($(this).text());
          } else {
           $(this).closest('ul').css('color', 'lightgray');
          }
      })
    })

  });
})```
<pre class="snippet-code-html lang-html prettyprint-override"><code><script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<main>
  <div class="index__container">
     <section class="index">
        <ul class="index__header">
            <li>Project</li>
            <li>Filter: <select id="index__filter">
                <option selected="selected" value='ALL'>All</option>
                <option value="Pedagogical Explorations">Pedagogical Explorations</option>
                <option value="Research Production">Research Production</option>
                <option value="Spatial Practice">Spatial Practice</option>
                <option value="Exhibition">Exhibition</option>
            </select></li>
            <li>Year</li>
        </ul>

            <ul class="index__entry">
                <li>Multiscale Strategies to Reactivate Transhumance in Spain</li>
                <li>
                    <span class="tag">Spatial Practice</span>
                </li>
                <li>2017</li>
            </ul>

            <ul class="index__entry">
                <li>Architecture after Speculation</li>
                <li>
                    <span class="tag">Research Production</span>
                </li>
                <li>2017</li>
            </ul>

            <ul class="index__entry">
                <li>Polyester Merino Chair</li>
                <li>
                    <span class="tag">Spatial Practice</span>
                </li>
                <li>2017</li>
            </ul>

            <ul class="index__entry">
                <li>1500 caracteres</li>
                <li>
                    <span class="tag">Spatial Practice</span>
                    <span class="tag">Research Production</span>
                </li>
                <li>2017</li>
            </ul>

            <ul class="index__entry">
                <li>Europan 13: Die Arbeitersiedlung</li>
                <li>
                    <span class="tag">Spatial Practice</span>
                </li>
                <li>2015</li>
            </ul>

            <ul class="index__entry">
                <li>Asymmetric Meta-Mapping</li>
                <li>
                    <span class="tag">Pedagogical Explorations</span>
                </li>
                <li>2017</li>
             </ul>

            <ul class="index__entry">
                <li>Chicago Architecture Biennial</li>
                <li>
                    <span class="tag">Spatial Practice</span>
                    <span class="tag">Research Production</span>
                    <span class="tag">Exhibition</span></li>
                <li>2015</li>
            </ul>

    </section>
</div></code>```

Body:
I am trying to filter a 'Project Index' by tags using jQuery and CSS.

I am currently taking the .val() of the selected option in a <select> dropdown list and checking if it's equal to the inner .html() of a .tag. If they match it will make the project entry black, if else it will make it light gray.

My current code works when the project has one tag, but once there are multiple tags it breaks. My guess is that because although there is one .tag equal to the selected dropdown value, the other .tag are not,  therefore using the else condition?

What am I missing? Is there a better/more efficient way to do this?

HTML

Project

Filter: <select id="index__filter">
                <option selected="selected" value='ALL'>All</option>
                <option value="Pedagogical Explorations">Pedagogical Explorations</option>
                <option value="Research Production">Research Production</option>
                <option value="Spatial Practice">Spatial Practice</option>
                <option value="Exhibition">Exhibition</option>
            </select>

Year

Multiscale Strategies to Reactivate Transhumance in Spain

                    Spatial Practice

2017

Architecture after Speculation

                    Research Production

2017

Polyester Merino Chair

                    Spatial Practice

2017

1500 caracteres

                    Spatial Practice
                    Research Production

2017

Europan 13: Die Arbeitersiedlung

                    Spatial Practice

2015

Asymmetric Meta-Mapping

                    Pedagogical Explorations

2017

Chicago Architecture Biennial

                    Spatial Practice
                    Research Production
                    Exhibition

2015

JS

  // Filter Project Index
  var $indexSelect = $('#index__filter');
  var $indexEntry = $('.index__entry');
  var $tag = $('.tag');

  $indexSelect.change(function(){
    var selectedValue = $(this).val();
    if(selectedValue == 'ALL'){
       $indexEntry.css('color', 'black');
     return;
    }

    $tag.each(function(i,option){
     if ($(this).html() == selectedValue) {
        $(this).closest('ul').css('color', 'black');
        console.log($(this).text());
      } else {
       $(this).closest('ul').css('color', 'lightgray');
      }
    });
  });

Body:
Because you're looping trough all the tags, and aply styling for each tag it will only show the styling for the last tag of each entry.

If you loop per entry, and than per tag in each entry you can break out of the loop once you have found a tag that matches the selected tag.

// loop trough each entry
$indexEntry.each(function(i,entry){
  // loop trough tag iwithin the entry
  $( this ).find( '.tag' ).each(function(i, tag){
    if ($(this).html() == selectedValue) {
        $(this).closest('ul').css('color', 'black');
        // exit this loop as soon as we've determined it should be black
        return false;
    } else {
       $(this).closest('ul').css('color', 'lightgray');
    }
  })
})

$(function(){
// Filter Project Index
  var $indexSelect = $('#index__filter');
  var $indexEntry = $('.index__entry');
  var $tag = $('.tag');

  $indexSelect.change(function(){
    var selectedValue = $(this).val();
    if(selectedValue == 'ALL'){
       $indexEntry.css('color', 'black');
     return;
    }

    $indexEntry.each(function(i,entry){
      $( this ).find( '.tag' ).each(function(i, tag){
        if ($(this).html() == selectedValue) {
            $(this).closest('ul').css('color', 'black');
            return false;
            console.log($(this).text());
          } else {
           $(this).closest('ul').css('color', 'lightgray');
          }
      })
    })

  });
})

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<main>
  <div class="index__container">
     <section class="index">
        <ul class="index__header">
            <li>Project</li>
            <li>Filter: <select id="index__filter">
                <option selected="selected" value='ALL'>All</option>
                <option value="Pedagogical Explorations">Pedagogical Explorations</option>
                <option value="Research Production">Research Production</option>
                <option value="Spatial Practice">Spatial Practice</option>
                <option value="Exhibition">Exhibition</option>
            </select></li>
            <li>Year</li>
        </ul>
        <a href="">
            <ul class="index__entry">
                <li>Multiscale Strategies to Reactivate Transhumance in Spain</li>
                <li>
                    <span class="tag">Spatial Practice</span>
                </li>
                <li>2017</li>
            </ul>
        </a>
        <a href="">
            <ul class="index__entry">
                <li>Architecture after Speculation</li>
                <li>
                    <span class="tag">Research Production</span>
                </li>
                <li>2017</li>
            </ul>
        </a>
        <a href="">
            <ul class="index__entry">
                <li>Polyester Merino Chair</li>
                <li>
                    <span class="tag">Spatial Practice</span>
                </li>
                <li>2017</li>
            </ul>
        </a>
        <a href="">
            <ul class="index__entry">
                <li>1500 caracteres</li>
                <li>
                    <span class="tag">Spatial Practice</span>
                    <span class="tag">Research Production</span>
                </li>
                <li>2017</li>
            </ul>
        </a>
        <a href="">
            <ul class="index__entry">
                <li>Europan 13: Die Arbeitersiedlung</li>
                <li>
                    <span class="tag">Spatial Practice</span>
                </li>
                <li>2015</li>
            </ul>
        </a>
        <a href="">
            <ul class="index__entry">
                <li>Asymmetric Meta-Mapping</li>
                <li>
                    <span class="tag">Pedagogical Explorations</span>
                </li>
                <li>2017</li>
             </ul>
        </a>
        <a href="">
            <ul class="index__entry">
                <li>Chicago Architecture Biennial</li>
                <li>
                    <span class="tag">Spatial Practice</span>
                    <span class="tag">Research Production</span>
                    <span class="tag">Exhibition</span></li>
                <li>2015</li>
            </ul>
        </a>
    </section>
</div>


问:
It is possible to interpolate Typescript where the variable is a string?
I need to interpolate a variable which is a string, but this no working.
Is there any way to interpolate this variable? Is it better to do the substitution directly?

for example:

```<code>time = duration.years();
dateTime = this.i18nService.getTranslation('past-date-years');
//dateTime value is = "${time} years ago"

console.log(`${dateTime}`); //not working

console.log(`${time} years ago`);//working
</code>```

答:
Since your string interpolation syntax is correct, this would mean that either dateTime is null or an empty string. Please add the output of your logged strings to your question and/or any errors that are showing up in the console.

Based on your comments below, it seems that you have a string interpolation within a string interpolation where the first hasn't been evaluated.

The following (rudimentary) code works:

```<code>let time = "This is time";
let vari = `${time} | is what we got`;
let result = `${vari} | is this possible?`;
document.body.innerText = result;
</code>```

...which will print the result with all the variables resolved, but that's because TypeScript knows how to break those lines apart and construct a normal concatenation from them.

It seems that in your instance, getTranslation() isn't resolving time, but is instead constructing an escaped string with the interpolation tokens in it. That needs to be resolved appropriately.

Since TypeScript compiles to different targets, and string interpolation is essentially TypeScript doing string concatenations behind the scenes, you're going to have to do some legwork to write the code and evaluate the resulting JavaScript to see if it gives valid output that will resolve the variables appropriately.

Head over to the TypeScript play, and use that to check the output. You'll have to plug in some of what the getTranslation() method is doing, and see if the output will generate appropriately.

Body:
I need to interpolate a variable which is a string, but this no working.
Is there any way to interpolate this variable? Is it better to do the substitution directly?

for example:

time = duration.years();
dateTime = this.i18nService.getTranslation('past-date-years');
//dateTime value is = "${time} years ago"

console.log(`${dateTime}`); //not working

console.log(`${time} years ago`);//working

Body:
Since your string interpolation syntax is correct, this would mean that either dateTime is null or an empty string. Please add the output of your logged strings to your question and/or any errors that are showing up in the console.

Based on your comments below, it seems that you have a string interpolation within a string interpolation where the first hasn't been evaluated.

The following (rudimentary) code works:

let time = "This is time";
let vari = `${time} | is what we got`;
let result = `${vari} | is this possible?`;
document.body.innerText = result;

...which will print the result with all the variables resolved, but that's because TypeScript knows how to break those lines apart and construct a normal concatenation from them.

It seems that in your instance, getTranslation() isn't resolving time, but is instead constructing an escaped string with the interpolation tokens in it. That needs to be resolved appropriately.

Since TypeScript compiles to different targets, and string interpolation is essentially TypeScript doing string concatenations behind the scenes, you're going to have to do some legwork to write the code and evaluate the resulting JavaScript to see if it gives valid output that will resolve the variables appropriately.

Head over to the TypeScript play, and use that to check the output. You'll have to plug in some of what the getTranslation() method is doing, and see if the output will generate appropriately.


问:
Is it better to return a view from a controller action, or to use ajax requests and redirect to a url?
I'm currently developing a web application using C# with the MVC framework and I've stumbled upon an interesting question.

I was programming some server-side validation and found that I needed to make an ajax request to a controller, make that controller return an URL, and then use javascript to redirect to that URL. This was needed in this particular case since I was working with model validation in a partial view(inside a modal).

My question is: Is it better to return a view from a controller(Actionresult/Viewresult)?

Controller.cs

```<code>[HttpPost]
public ActionResult AddLeverancier(Leverancier leverancier)
{

   return RedirectToAction("Index");
}
</code>```

or redirect to a URL from Javascript?

Controller.cs

```<code>[HttpPost]
public ActionResult DeleteAllLeveranciers()
{

    return Json(Url.Action("Index", "Leverancier"));
}
</code>```

javascript.js

```<code>        self.baseManager.DoAjaxRequest("POST", self.baseURL + "/DeleteAllLeveranciers", null, function (data) {
        window.location.href = data;
        self.baseManager.HideModal("deleteAllLeveranciersModal");
    });
</code>```

Is there any risk/performance issue related to this? Does it make any significant difference?

Thank you in advance,

Mick

答:
It is all depend on how fluent you want at client-side.

In ASP.NET MVC, I personally like to use full post-back for HttpPost, as I like strongly typed server-side language for unit tests and integrated tests. It is not easy to unit test JavaScript embedded inside html. (If I use Angular, it is totally different story.)

For simple HttpGet which doesn't require any validation, I like to use Ajax.

Body:
I'm currently developing a web application using C# with the MVC framework and I've stumbled upon an interesting question.

I was programming some server-side validation and found that I needed to make an ajax request to a controller, make that controller return an URL, and then use javascript to redirect to that URL. This was needed in this particular case since I was working with model validation in a partial view(inside a modal).

My question is: Is it better to return a view from a controller(Actionresult/Viewresult)?

Controller.cs

[HttpPost]
public ActionResult AddLeverancier(Leverancier leverancier)
{

   return RedirectToAction("Index");
}

or redirect to a URL from Javascript?

Controller.cs

[HttpPost]
public ActionResult DeleteAllLeveranciers()
{

    return Json(Url.Action("Index", "Leverancier"));
}

javascript.js

        self.baseManager.DoAjaxRequest("POST", self.baseURL + "/DeleteAllLeveranciers", null, function (data) {
        window.location.href = data;
        self.baseManager.HideModal("deleteAllLeveranciersModal");
    });

Is there any risk/performance issue related to this? Does it make any significant difference?

Thank you in advance,

Mick


问:
Inline SVG vs CSS-background Sprite
I'm creating a few pages in my app (currently running Angular on my front-end) that each contain a good deal of logos. I'm currently creating directives for each SVG logo (putting the inline SVG code in a template), which makes the code a lot more readable, but due to the number of logos, I'm starting to wonder if it would make more sense to create a CSS sprite instead. </p>

<p>I would appreciate some thoughts from a performance perspective on this. I know CSS background images get cached, so that's a plus. SVG offers me more flexibility if I want to, say, color or size some specific logos differently, but if it's costing me a fair amount in terms of loading time I'd rather opt for the background image. </p>

答:
I'm doing something like this for the company I work for. They have hundreds of images that could easily compress into one SVG sprite. I guess the answer depends on the project, will it get bigger? if yes I think taking the time to implement the sprite sheet now would be a great idea, also you could use it for icons. here is a great article on CSS tricks.

If you will start doing that I recommend using Grunt and implement grunt-svgstore it saves a ton of time creating the sprite sheet for you and it's pretty simple to implement, something like this.

```<code>grunt.initConfig({
  svgstore: {
    options: {
      option like prefix ID with 'icon', indentation, etc.
      }
    },
    default : {
      files: {
        'dest/dest.svg': ['svgs/*.svg'], //destination, files to convert
      },
    },
  },
});
</code>```

Title: Inline SVG vs CSS-background Sprite

Body:
I'm creating a few pages in my app (currently running Angular on my front-end) that each contain a good deal of logos. I'm currently creating directives for each SVG logo (putting the inline SVG code in a template), which makes the code a lot more readable, but due to the number of logos, I'm starting to wonder if it would make more sense to create a CSS sprite instead.

I would appreciate some thoughts from a performance perspective on this. I know CSS background images get cached, so that's a plus. SVG offers me more flexibility if I want to, say, color or size some specific logos differently, but if it's costing me a fair amount in terms of loading time I'd rather opt for the background image.

Body:
I'm doing something like this for the company I work for. They have hundreds of images that could easily compress into one SVG sprite. I guess the answer depends on the project, will it get bigger? if yes I think taking the time to implement the sprite sheet now would be a great idea, also you could use it for icons. here is a great article on CSS tricks.

If you will start doing that I recommend using Grunt and implement grunt-svgstore it saves a ton of time creating the sprite sheet for you and it's pretty simple to implement, something like this.

grunt.initConfig({
  svgstore: {
    options: {
      option like prefix ID with 'icon', indentation, etc.
      }
    },
    default : {
      files: {
        'dest/dest.svg': ['svgs/*.svg'], //destination, files to convert
      },
    },
  },
});